Swift Core Data - DataModel Entity Relationships - swift

I'm still unsure whether I understand entity relationships. Just to confirm can I get someone to walk me through what I have created and confirm whether it is correct?
Data Model
So I'm creating a quiz app. This is my understanding of the above :
Category Entity - (e.g. geography) has a many to one relationship with QuizName. A single category can have multiple QuizNames.
A quizName (e.g. rivers in China) can have multiple Question entities. e.g. 'Which of one of these rivers are in China'
A Question can then have 4 possibleAnswers from which the person can choose from.
Have I made the data model correctly?
Thanks.

This model looks good, but Quiz seems better than QuizName.
If --->> is a one-to-many relationship:
Category --->> Quiz --->> Question
A Question entity could either have 4 String properties that represent answers or if each answer has specific attributes than maybe an answer should be yet another entity.

Related

Can an entity have a list/array of items (Core Date, XCode)

I'm very new to Core Data and I have two questions:
I want that all of my Patient entities have property bed which is a value of type bed... Can I create an entity for that too and connect always one patient with one bed?
I wondered if I can do something like every Patient has a property doctors, and that would be a array of doctors "[doctor]". How could I make this.
Thanks, hope you know what I mean, it would be great If someone knows how to do that.
Okay Larme and Joakim Danielson answers my question as comments under my post :)
Their comments:
Yes. The key word you are missing is "relations". You want relationship between your entities. Be it one to one, one to many, many to many. –
Find an online tutorial on learning and using Core Data, many of them handles entity relationships as well –

Trying to understand and build a Core data model using relationships

So i have done some research on Core data relationships with Swift, and i have a base understanding of the functionality, but i wanted to see if i could get some help on my specific model. What i want to do is get a user inputted question and answer and have that pair or pairs of questions and answers be saved to Core Data under a name. For the model, i was thinking i need to create a Questions entity with an attribute question, an Answers entity with an attribute answer and a Name entity with an attribute name. This is where i get confused on how i can make this work, or if it is even a correct model in order a deck name to be given, questions and answers be input and saved to that name only. Each time a new name is created, i want the new questions and answers to be saved to that name and so on. Thanks in advance for any help that can be given.
Name -->> Question (one to many relationship)
Question --> Answer (one to one assuming there's just one answer per q)
Then you need to create reverse relationships for all of the above.
This is how it should look like in the editor:

Is it a one-many relationship in Core data?

I have category entity and subcategory entity. I need to get subcategory data to that related categoryId of category entity.
My category entity contains these attributes: "categoryId","categoryName"
subcategory contains: "subcategoryId","subcategoryName", "categoryId".
So can any one please guide me how can i put the relationship between this two entity ??
Thanks for advance.
Very first you are mixing the concepts of MySQL or SQLite with Core data. Unlike them Core Data does not have primary-foreign Key concept to relate entities(for easy understanding tables in MySQL). Just create relationship between those entities and you can fetch data their data.
Now about your Entities you have are category and subcategory. So you have to create relationship between them. If one category have many subcategories you have to check To many relationship option from Data Model Inspector..Otherwise One to One relationship would be the one you should go for..Have a look at screenshot how you can make your relationship one to many..
This is a good tutorial link for one to many relationship. You can refer if you do not know how to implement.
Also this for tutorial simple relationship in Core Data..
if you are beginner with Core data you can go with Quick Tutorial Start by Apple and you will get basic idea of Core data.

Saving a One To Many Relationship in CoreData

I have created a core data model that has two entities which have a one to many relationship. The entities are Exams and Questions. An Exam can have many questions.
What is the best way to save the Questions entities so they would be associated with the specific Exam?
The flow I want it to have is to start a new exam with an exam name, then add questions, then close out the exam with the questions count and save it to the persistent store.
After creating a Question object, just set its .exam property (provided that's the name of the inverse relationship to e.g. Exam.questions) to the containing exam object. If you need to order the questions, have a look at ordered relationships (available since Lion / iOS 5) or this or this.

Copying entities in Core Data

I have a couple of Core Data entities... Student and Exam.
Now, the Exams is initially just one object per exam - Maths Exam 3, English Exam 2 etc.
There is a relationship between Students and Exams in my data model (a student can have several exams). But initially, the Exams are just floating free, and not attached to any students.
How would I make a copy of one of the exams and attach it to a student?
If I do something like:
[student addExamsObject:examObject];
...then I think it simply references the original exam to the student, rather than making a copy.
I need a copy because the Exam has a boolean 'hasTaken', which is YES when the student has taken the exam. But if I set that now, it will make it seem like all the students with that exam have taken it.
Clarification: I would rather not restructure my model. The data is taken from a couple of xml files, one each for Students and Exams, which are parsed into the Core Data store. For instance, an Exam object might look like this:
name:Maths 5
class-id:12
year-id:4
student-id:0
..with a Student object looking like
name: Dave
class-id:12
year=id:4
student-id:222
Various rules are meant to guide which exams get attached to which students... for instance if all the Exam's ids are 0 then all students take the exam. If class-id and year-id match, and student-id is 0, then the Exam gets added to students with the same class and year. If the student-ids match, then just that student takes the Exam. etc etc.
I cannot change the way the xml is outputted from the server.
Another issue is that Exam has too-many relationship to a Question entity... in other words, the questions in the Exam. And I have to store answers to the questions that each student gives in an exam.
Edit: I wish people would try to answer my question rather than tell me to restructure my whole program. There are reasons why the data model has been structured like it is.
Edit2: Maybe I will have restructure....
Exam shouldn't have a hasTaken property. Think about it in the real world. An Exam would not know about who has taken it because many people could have taken it. The instance of taking an exam, then, should be a first-class concept in your model.
Consider this:
Exam has many TakenExams, TakenExams belongs to Student http://yuml.me/6627495d
Now the concept of taking an exam is a real object, you can then model assocation metadata as well, such as dateTaken, score, and so on.
Also remember that Core Data expects you to have all of your inverse associations set up as well.
You don't usually copy an entity. (I'm not sure what happens if you call copy on an NSManagedObject... it's not explained in the documentation, as far as I know. Experts can correct me. )
Just create another entity, or write a method which does just that.
I think another way is to make many-to-many relationships between Exam and Student:
create relationships in Exam called studentsToTakeThisExam and studentsWhoTookThisExam.
create relationships in Student called examsToTake and examsAlreadyTaken.
and set up the inverse relationships accordingly.
I would not argue (as You requested) if your modeling is correct or not. The procedure to copy an entity is, in general, quite complex, owing to the fact that, besides attributes, you also need to deal with the entity's relationships and copy them. I can not post here a huge amount of source code showing how to accomplish this, however, I can point you to a book where this issue is described in detail, with all of the source code you need. The book is the one from Marcus Zarra, "Core Data Apple’s API for Persisting Data on Mac OS X" by "The Pragmatic Programmers".
You really don't want to copy an Exam in this situation. You'd end up with lots of identically named Exams which didn't have a relationship with each other, and then you'd be forced to group them together (if you wanted to) by their name.
I'd recommend a new entity (perhaps "ExamSitting"?) which represents a Student sitting an Exam. You could then a to-many from Student to ExamSitting, and a to-many from Exam to ExamSitting. This enables you to have as many attributes on the ExamSitting as you like then (hasTaken, grade and so on).
Edit
Okay, given your clarification, I have a point or two to add (although they may not be what you're looking for). I understand that you're loading from files with a particular structure, but that doesn't necessarily have to dictate your structure.
With the XML files laid out as you now describe, I would still use an Exam - Student - ExamSitting model. If I were to implement it, I'd load all the Students, and then, for each record in the Exams file, I'd create one Exam object, and then a number of ExamSitting objects, one for each Student that fits the criteria defined in the record. As I mention above, this enables you to store more information about each event, such as mark, takenDate and so on.
If you're sure there's no requirement to be able to store additional information at this granularity, you could just create a to-many relationship studentsTakingExam. This could be populated as you load each exam record by querying the loaded Student entities.