0

I have a Core Data database with Employees and Departments. Each employee belongs to one department and each department has many employees. So far, so good. I want to add the ability to store, for each department, their current Employee of the Month, which would point to one Employee at a time.

When I do this as a relationship, I get the warning that the relationship should have an inverse relationship. But the employee already belongs to the department, and it doesn't seem to make sense to create for each employee a relationship of "department where I'm employee of the month" which for all but one employee in each department, would be nil. (Not trying to track a history of an employee's kudos in the database.)

It seems, from reading the high-level descriptions, like this is the sort of use where a Fetched Property would work well -- a 'weak, one-way relationship', but most articles describing how to implement a Fetched Property (a) use Objective C code rather than Swift, and/or (b) go into far more complexity than it seems like this should need. The use case isn't about fetching something with a predicate, just assigning it. All I want to do is:

thisDepartment.employeeOfTheMonth = thisEmployee

and then later

recognitionStr = thatDepartment.employeeOfTheMonth.name

Is there a better way to go about this? Or is Fetched Properties the right approach? And, if the latter, what is the simple, straightforward way to set up the employeeOfTheMonth relationship, in Swift? Thanks!

ConfusionTowers
  • 911
  • 11
  • 34
  • Maybe not what your looking for but "Employee of the Month" doesn't really belong to Department but rather as a separate entity with relations to Department and Employee and a date attribute for the month of the reward. – Joakim Danielson Aug 15 '18 at 20:18
  • Each department has their current Employee of the Month, and that's what I want stored for each department. Not interested in tracking the history of who was the E-of-the-M last month, prior month, etc, just "who is IT right now, for (this) department." – ConfusionTowers Aug 15 '18 at 20:21
  • Sure, just a comment. Create a relationship then, the inverse relationship might look awkward but it is mostly needed for Core Data and you don't need to use it in your code. – Joakim Danielson Aug 15 '18 at 20:27

1 Answers1

0

As far as I know, Core Data needs the inverse to work well. So one option is just create an inverse relationship on Employee. It's awkward, but you'll never use it in your code, so... it's not so bad?

But how I would do it (caveat: I've never used fetched properties): I would add an attribute on Department that'd be something employeeOfTheMonthID. Then I would write a property on the Department class like this:

var employeeOfTheMonth: Employee? {
  get {
    guard let id = employeeOfTheMonthID else { return nil }
    let fetchRequest = NSFetchRequest<Employee>(...)
    fetchRequest.predicate = NSPredicate(format: "employeeID == %@", argumentArray: [id])
    fetchRequest.fetchLimit = 1
    return (try? managedObjectContext?.fetch(fetchRequest))?.first
  }
  set {
    employeeOfTheMonthID = newValue?.employeeID
  }
}
Shinigami
  • 2,123
  • 23
  • 40