Department's "Employee of the Month" -- Fetched Property? How? Or something else?

78 Views Asked by At

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!

1

There are 1 best solutions below

0
On

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
  }
}