Core Data releationship confusion - iphone

If I have two entities; Foo and Bar. And Foo has two properties; bar1 and bar2 of type Bar. Now does Foo have a one-to-many releationship to Bar? At least should it be modeled as that in Core Data? Or is it two one-to-one releationship? How do I set that up properly in Core Data with inverse? The one-to-many releationship I understand but not the last releationship type? Is that even possible or good way to that?

And Foo has two properties; bar1 and bar2 of type Bar. Now does Foo
have a one-to-many releationship to Bar?
No, Foo has two relationships with Bar, and those relationships are named bar1 and bar2. Whether they're "to-one" or "to-many" depends on how you specified them. Select each in the model and see whether the "to-many" checkbox is checked.
At least should it be modeled as that in Core Data?
That depends on what you're trying to model. Do you want to have two separate relationships to specific object (that'd be two different "to-one" relationships), or do you want a single relationship to a group of objects (one "to-many" relationships)? Here's an example that might help clarify things...
A business may have zero or more employees. A business also has a single chief executive officer and a single chairman of the board. So the Business entity might have a "to-many" relationship named employees with the Person entity. It might also have "to-one" relationships named ceo and chairman, again with Person. Those might not be strictly necessary -- maybe the CEO and Chairman are both employees, so you could find them by searching the set of employees and filtering by job title. But it can be handy to have them as separate relationships if you're going to use them often and don't want to have to search through thousands of other employees every time you do.
How do I set that up properly in Core Data with inverse?
Again, it'll depend on what you're modeling. For example, the inverse of the employees relationship would be Person's employer "to-one" relationship.

Entities have several different kind of properties, they have attributes and relationships (and fetched properties, but that's beside the point). It sounds like Foo and Bar are two classes you created with Foo having Bar properties. Then you want assimilate those as Entities in a Core Data model.
Typically, things are done the other way around. You create Entities in the Core Data model editor. You then link the entities by creating relationships. If you add a relationship from Foo to Bar, then it is good practice to create an inverse relationship from Bar to Foo.
Create the relationship from Foo to Bar
Create the relationship from Bar to Foo
Select that last relationship and set its inverse to the first one
Now if you want Xcode to generate the matching NSManagedObject subclasses Foo and Bar, then you can select the Entities and in the Xcode Editor menu, select "Create NSManagedObject subclasses"
You'll then see you're two classes with the proper attributes to match how your model is set up.
I've authored a book on Core Data that explains all this is much deeper details.

This is two one-to-one releationship.
To make inverse just select you entity in inverse field (When you create relation).

Related

Core Data Inheritance - Manage Inverse relationships of subclasses

I am new to CoreData environment and I'm trying to understand how it works.
In my project, I have a superclass VetExam whose subclasses are Examination, Treatments and Vaccination, which share the same attributes of their superclass and has a reference to Pet class. On the other hand, Pet class holds an array of reference of every class except of VetExam, which should only be used for Polymorphism (so that I can use VetExam object and create a single view for each type).
Based on this model, I've tried to create entities in CoreData, but it seems that I have to specify for each type the inverse relationship for each entity. This represent a problem since from VetExam entity side the relationship is of type Pet but on Pet side is To-Many for each type of Examination, which does not allow me to get the inverse reference of VetExam.
Since this explaination can easily be misunderstood, I will show you the visual representation of it.
The problem is in VetExam entity, whose Inverse attribute is not known.
Does anyone know how to deal with this type of situation?
A preliminary note on inheritance...
Class inheritance
AND
Entity inheritance
For the second, I highlight the note in the Apple Documentation:
Be careful with entity inheritance when working with SQLite persistent
stores. All entities that inherit from another entity exist within the
same table in SQLite. This factor in the design of the SQLite
persistent store can create a performance issue.
What this means is that Core Data framework creates one large table in the SQLite database that includes the parent entity and the child entities. Such a large table inherently contains inefficiencies. While this may seem convenient for you to manage now in your model editor and in your NSManagedObject subclasses, this may cause inefficiencies / performance issues in the long run if you expect your app to persist and retrieve large amounts of data in the four entities you mention.
Advice from others is very relevant here because four separate entities will in my humble opinion be easier to manage, rather than one parent entity and three child entities. You do not have to give up the class inheritance you’ve developed in your code if you choose this option.
So, to answer your question...
My logic:
Every Pet may have many instances of VetExam during its life, but each instance of VetExam is carried out on only one Pet?
If yes, then create a one-to-many relationship between Pet and VetExam -
Pet <—>> VetExam.
Whatever occurs during the VetExam is any combination of one Examination, Treatment and/or Vaccination. That is and in an attempt to be clear, the VetExam may optionally have an examination, but it may not have a treatment or a vaccination. This is likely to change for each VetExam, therefore this is directly related to the VetExam, not the Pet.
If yes, then create optional one-to-one relationships between VetExam and the entities Examination, Treatment and Vaccination.
VetExam <—> Examination
VetExam <—> Treatment
VetExam <—> Vaccination
In this model, each entity relationship detailed above has an inverse.
Finally, it might be worth noting that in this proposed model, the relationship between a Pet and all the examinations, treatments and vaccinations it receives during its lifetime is stored against PetExam, not directly against the Pet.

How to properly define relationships in SuiteCRM

In the Module Builder, let's say I want to add custom modules Pets and Visits for my pet grooming salon.
If I want to be able to access Visits from a logic hook in the Pets module, and also Pets from Visits, and I also want to show each one as a panel in the other, should I:
Define a Many-to-One relationship from Visits (L) to Pets (R)?
Define a One-to-Many relationship from Pets (L) to Visits (R)?
Both?
I don't know if the answer's the same for Sugar; I think there might be a different "module builder" sort of thing for it.
As far as Sugar is concerned you'd want a many-to-many relationship if you want a panel in both modules.
However if you want to limit the relationship to a maximum of one Pet per Visit, then a one-to-many relationship is appropriate with Pet as primary module (L) and Visits as related Module (R).
Please note that in Visits the related Pet will possibly not be displayed as panel but as a relate field for such a relationship (at least in EditView, in Record View it probably is still displayed as Panel in SuiteCRM as it uses the old UI of Sugar).
Either way a relationship can always be accessed from both sides, so you don't need a second relationship)
Further info: https://support.sugarcrm.com/Knowledge_Base/Studio_and_Module_Builder/Understanding_Relationship_Creation_Options/
PS: If you want a one-to-many relationship but a panel even on the side where only one record of the other module can be linked to most at any time, then you can probably achieve this by creating a many-to-many relationship first and adjust the relationship's metadata to have true_relationship_type as one-to-many in code.

Target/Source and owning/not owning entities

I'm a bit confused about this naming convention.
What is the difference between them and are target/source interchangeable with owning/not owning?
One thing in particular is hard to understand:
"The main difference between a OneToOne and a ManyToOne relationship in JPA is that a ManyToOne always contains a foreign key from the source object's table to the target object's table, where as a OneToOne relationship the foreign key may either be in the source object's table or the target object's table"
JPA wikibooks
I can't imagine such situation in uni one-to-one
Differences between them are a little confusing. You should practice a lot to understand very well.
At first, you should understand some terminology:
Role : In every relationship there are two entities that are related to one another, and each entity is said to play a role in the relationship.
Direction : Relationships can be unidirectional or bidirectional. For e.g.. a Person has an address is normally unidirectional whereas Employee working on a project is normally bidirectional. We will look at how to identify and define directionality while coming up with a Data Model.
In order to have relationships at all, there has to be a way to create, remove, and maintain them. The basic way this is done is by an entity having a relationship attribute that refers to its related entity in a way that identifies it as playing the other role of the relationship. It is often the case that the other entity, in turn, has an attribute that points back to the original entity. When each entity points to the other, the relationship is bidirectional. If only one entity has a pointer to the other, the relationship is said to be unidirectional. A relationship from an Employee to the Project that they work on would be bidirectional. The Employee should know its Project, and the Project should point to the Employee working on it. A UML model of this relationship is shown here. The arrows going in both directions indicate the bidirectionality of the relationship (Form this book >> Pro JPA 2)
Then dive into this link (archived from the original)
I'd like to comment only the links, but I need 50 reputation

How to add mutiple entities for an attribute (iOS, Core Data)?

I want to create a one to many relationship. My setup is something like:
I have the Profile Entity,
I have the Time entity.
Every profile has a relationship to Time.
How can I define relationships, and add multiple Time entities to a single profile?
I bet it is obvious, but I can't see how to implement.
edit after posting the answer I saw your comment - to define a to-many relationship in the modeller, select the relationship and choose to-many from the options:
To populate the relationship, you can do it two ways. I am assuming your Profile entity has a to-many relationship called times and the inverse relationship is a to-one relationship called profile.
Set the profile on each Time entity as you are creating them. This will automatically populate the inverse relationship (i.e. add the Time to the times set of the profile).
Collect the relevant Time entities in a set and set the times property to this set. Again, the inverse will be automatically populated.
There is more information here. Accessor methods to add individual entities to a to-many relationship can be generated from the managed object model editor in Xcode.

CoreData modelling inverse relationship

Apple's documentation suggests the use of inverse relationships when modelling data models in CoreData.
I have the following example:
A Book (Entity) has several "pages" and one "frontCover" and one "backCover".
A Page (Entity) is in one "book" (so "book" is the inverse of "pages").
OK so far, that's the standard case...BUT now, my problem:
I only have one class Cover (Entity). A Cover (Entity) is on one "book". On this "book" the Cover is EITHER the "frontCover" OR the "backCover". So, the inverse of "book" is EITHER "frontCover" OR "backCover".
This cannot be modelled in CoreData. A relationship can only be the inverse of one relationship, but not of EITHER this OR that relationship.
What is the best way to model this? Unidirectional relationships (no invers)?
Thanks for your answers,
Chris
You could do something like the model below (first image). This would leaving of Cover's inverse relationships as nil. This doesn't feel right to me, though.
Another option (second image) would be to give Book a 'covers' relationship which references 2 Cover objects, and give Cover an isFront boolean attribute. This would allow for inverse relationship called 'book'.
One way to do it could be to create Cover as an "abstract" entity with two sub entities - FrontCover & BackCover. Then you could create the relationship & inverse to each of those.
I just want to add.
One way is to have 2 subentities. But that's useful only if FrontCover and BackCover differs a lot.
If they are exactly the same object, you should instead use an enum in the entities.
That enum differentiate whether the cover is frontCover or BackCover.
Then you set only 1 "to many" relationship from book to cover.
The purpose of coredata is to save your data. Your logic should be in the code anyway.
Also creating two subEntities is essensially the same with westSider's answer. Sub entities simply add another relationship on the original one.