One to Many Relationship
Intermediate Training Core Data
Now that you've gotten a good feel for what a one-to-one relationship looks like, let's explore a one-to-many relationship which is more appropriate for our application design. In this lesson, we'll modify our relationship and then let Xcode auto-generate the necessary file changes for us. Looking into our Core Data classes now, you can see that companies now have a set of employees. Let's now improve the Employee creation process so that we save our Core Data models properly.

Comments (13)
endodoug
5 years ago
Aha! .allObjects -> that's a little nugget of gold.
K1llarney
5 years ago
Hi Brian, Just sharing my experience... I name my relationships with the prefix of 'has'. ie: Company -> hasEmployees -> Employee Employee -> hasCompany -> Company I find this reads better in code. Just my 2c (2 pennies) worth. Thanks
Brian Voong
5 years ago
K1llarney
5 years ago
ah, ic. No, that was not my intention and I didn't think beyond the way it read in the context of relationships. Thanks
K1llarney
5 years ago
Hi Brian, I am following your course and learning so much, so a big thank you for your knowledge and time. I’m tweaking my training app to incorporate some of my own knowledge and style. This has worked for the first 19 lessons, but I have hit an issue with the One to Many lesson. I was wondering if you could take a quick look at the below code and try to help me understand why my ‘createEmployee’ function is NOT storing the company name. After creating a new employee, the new person is created with an employeeName, but the company name ie: relationship is nil. Thanks in advance. CoreData Entity Company Attribute name Relationship hasEmployees -> Employee -> hasCompany (one-many) Entity Employee Attribute name Relationship hasCompany -> Company -> hasEmployees (one-one) @objc private func handleSave() { guard let name = nameText.text else { return } guard let company = companyPassed else { return } dismiss(animated: true) { let employeeName = CoreDataManager.shared.createEmployee(employeeName: name, newCompany: company) self.delegate?.didAddEmployee(newEmployee: employeeName!) } } func createEmployee(employeeName: String, newCompany: Company) -> Employee? { let employee = Employee(context: moc) employee.name = employeeName employee.hasCompany?.name = newCompany.name ad.saveContext() print(employee) return employee }
Brian Voong
5 years ago
K1llarney
5 years ago
Thanks for your response and you are correct, it's an abstracted method for saving core data context. Just a short cut I use based on two lines in my AppDelegate file. After a good nights sleep, I fixed my issue by replacing the createEmployee function with this... ~~~~~~~~~~~~~~~ func createEmployee(employeeName: String, newCompany: Company) -> Employee? { let taxID = "49-1" let state = "SF" let newEmp = Employee(context: moc) let newTax = EmployeeInfo(context: moc) let newAdd = Address(context: moc) newEmp.name = employeeName newEmp.hasCompany = newCompany newTax.hasEmployee = newEmp newTax.taxID = taxID newAdd.hasEmployee = newEmp newAdd.state = state ad.saveContext() return newEmp } ~~~~~~~~~~~~~~~ Now when I return the employee object, it has a company, state and taxID 'linked' to it. Onward to more lessons. Thanks
nerddd
5 years ago
To make it more clear you can set employee to its array when company data didSet: var company: Company? { didSet { guard let companyEmployees = company?.employees?.allObjects as? [Employee] else { return } guard let companyName = company?.name else { return } self.employees = companyEmployees self.title = companyName } }
Gabriel
5 years ago
Brian - how would one go about ensuring all the many relationships (employees) are deleted when a Company is deleted?
Juanpablo Macias
5 years ago
Extremely helpful video. I'm finally coming back after a break from coding. It is good to learn and refresh! Thank you!
Beyond2021
4 years ago
Thanks for the video Brian. Since I redid the "fetchEmployees", one to many relationship, my employees stop persisting. Am I doing something wrong? Thanks
Brian Voong
4 years ago
Beyond2021
4 years ago
Thanks Again Brian! You are absolutely correct . I was creating a new company with let company = Company(context : context) instead of using the company belonging to the to the employee (generated)I was trying to persist.
thearley
4 years ago
First I created 6 employees for the company XYZ Corp. From Companies screen I then deleted the XYZ Corp. I used the software Datum to review the data. I found that the company XYZ Corp is deleted in Company, but the 6 employees are still in the entity Employee. What is the best way when deleting a company to delete any relationship entity that has data (6 employees in Employee). Thanks
Cinquain
4 years ago
I was ill for a couple of days... Glad to be back!
Hwang.the.human
4 years ago
Hello, Brian! For instance, what if I want to pull out all employees that belong to a specific company? And display it outside of EmployeesController. How can I do that? I am creating my own app and I am stuck...
Cinquain
4 years ago
Fire
ericathanas
3 years ago
What would someone do for a many-to-many relationship. For example, I'm working on a flashcard app and I want a user to be able to create a deck, say "Art History 101", but then also add those cards to other decks such as "Michelangelo" and "Da Vinci". So a card can be in many decks and a deck can have many cards. I've looked everywhere online and it seems like many-to-many is either not possible or discouraged but I'm unsure how to achieve what I want otherwise.
Brian Voong
3 years ago
ericathanas
3 years ago
I think I may have figured out where I was stumbling. I was trying to assign an array to the decks relationship in the card object but it was requesting an NSSet. I just converted it using NSSet(array: ) and it seems like it may have worked. The Apple documentation says that one must define many-to-many relationships in both directions, so it may not be perfectly resolved but as far as I can tell it is. I will continue on and note this part of my code as somewhere to investigate should errors occur in the future. Thanks so much, Brian! Your courses are amazing and I love doing them.
froggomad
3 years ago
Awesome, I've been trying to figure out how to link entities like this for a while. Your videos always get me where I can't quite get on my own. Just a small note: we can also chain the lets in the guard to make them a little more concise, and keep the code just about as readable. The else is indented by most, but I like to make it look more like a block by butting it up to the guard. Some also leave it hanging off the final let... guard let foo = foo, let foo2 = foo2 else { return }
HELP & SUPPORT