Modeling a to-many relationship in Core Data - iphone

I asked this question earlier, but I'm missing one important thing. I have a NoteObject entity and every note, without Core Data, just has an arrayOfTags (which is an array of NSStrings). I decided to use to-many relationships to store the tags instead of an array. So I created a new "Tags" entity, and set up a to-many relationship from my NoteObject to Tags. This works great when every tag is related to only one note, but I'm unsure how I would go about linking one tag with multiple notes. How would I set up that relationship?

In you data modeler just make the Tags -> Notes relationship a to-many relationship. If you have already generated the Entity subclasses you will have to redo those. You will also have to be careful when creating tags to ensure uniqueness, but other than that it should be fairly straightforward. myTag.notes should work just as well as myNote.tags.

Related

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

Delete nsmanagedboject from context with many to many relationship core data iOS

My model have 2 Entity (Category and News) with many to many relationship: (It mean a category may have many news and a news article may belong to one or more Category).
Below is my design:
Entity 1:
Category (attributes: categoryID, title, show, position) and a relationship with News Entity called "news".
"news" relationship has destination is "News", inverse relationship is "categories", type to-many relationship and delete rule is cascade.
Entity 2:
News (attributes: newsID, quote, content, link) and a relationship with Category Entity called "categories".
"categories" Relationship has destination is "Category", inverse relationship is "news", type to-many relationship and delete rule is nullify.
Object graph look like this:
News <<-------------->> Category
My question is:
1> Is my designed model is good ?
2> Arcoding to my designed model, if I delete a News object from it context example like:
id newsObjectToDelete = ....
[managedObjectContext deleteObject:newsObjectToDelete];
Does Category object that newsObjectToDelete belong to automatically remove newsObjectToDelete from NSSet of relationship "News".
3> If I want to constraints that a "News" must belong to at least one "Category". How to implement that constraints
Thank in advance. Sorry for poor English
It's tough to say whether or not this is a good fit for your app, but it looks like a pretty standard relationship.
If you delete an object, it is automatically removed from all Core Data relationships. Don't worry about a dangling reference to some deleted object, Core Data handles that for you.
Core Data can really only generate an error (and blocking the save) or take some automatic action during the save. You can do either of the following:
In Your Data Model: Using the data model editor, uncheck "Optional" for this relationship, and/or set the "Minimum" count to 1:
In Your "News" Subclass: If you need more fine-grained control and/or error reporting, you can check this during validation (to generate an error) or maybe take some automatic actions during the save process.
Note that using validation (either in the model or in your code) is only going to help during the development and debugging processes - calling -save: on the managed object context will fail, returning NO and generating an error. This should be a last resort, and really just there to keep bad data from getting into your persistent store. A validation failure like this tells you that some other part of your code is wrong and generating bad objects.

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.

fetchedresultscontroller with two entities - predicate to target each entity?

My iPhone app has a summary page (UITableView) where I would like to show a quick overview and therefore I need to get info from several entities. It was suggested to create an abstract parent entity and have my two entities as children of this one. This do allow me to fetch the two entities using the one fetchedresultscontroller.
This works but I find that I need to filter the return a small bit. Because of the 'hack' above these entities have nothing in common so I need completely separate predicates.so from EntityA I would need "color = blue" and from EntityB "length >= 10". Because the entity I'm actually querying have none of these this doesn't work at all.
Is there a way to do this or what's the best approach here?
Niether the UITableView or the NSFetchedResultsController is designed to deal with more than one entity at a time. Moreover, it seldom makes any sense to try to do so. If you find yourself in such a situation, you probably need to rethink your data model design.
If entities are logically associated with each other then they should be linked by a relationship. If data from any two objects is to be displayed in the same tableviewCell without being gibberish then they must have some logical association and therefore should be linked by a relationship of some kind. To display in the table, you fetch one side of the relationship and then walk the relationship/s to find the other related objects.
If the logical association is strong, it should be defined as a formal relationship in the data model e.g.:
EntityA{
//... some attributes
b<-->B.a
}
EntityB{
//...some attributes
a<-->A.b
}
However, if the relationship is weak or transient, then you should use a fetched property to relate them. The fetched property dynamically searches for other entities based on a preprogrammed fetch.
EntityA{
creationDate:date
someBs--(creationDate=$FETCH_SOURCE.creationDate)-->B
}
EntityB{
creationDate:date
}
A key concept here is that Core Data is providing the entire model layer of your Model-View-Controller design. It is not just a dumb database but an active object graph that models both the data itself and its behavior. Once you have a properly designed data model, problems with the controllers and views resolve themselves automatically.
If i understand correctly, you can use notifications and send a dictionary of required information to the UITableView view controller class.

RIA services presentation model with 1-many or many-many relationships

I'm trying to get a presentation model (discussed here and here) working in RIA. All the examples I can find are simple, flat data entities with no 1-many or many-many relationships, which are what I can't get working - specifically, on updates and inserts into associative relationships.
Queries I can get working fine - I have my presentation classes marked up with Association attributes (and Include attributes, where appropriate), and I have a good understanding about how data is loaded into the client side and maintained there as entities. I also have inserts of new entities covered. However, I'm experiencing the following problems. For the following examples, assume we have simple Album and Artist entities, where an Album has a single artist and an Artist can have zero to many albums. Both have a Name property.
On the client side, if I do myArtist.Albums.Add(anAlbum) or myArtist.Albums.Remove(anAlbum), nothing happens. HasChanges returns false. (Note that myArtist and anAlbum were obtained solely in code by loading the entities and iterating to get references to specific entities: I'm not doing anything in UI or with DomainDataSources yet, just dinking around).
If I update the Name on an Artist and SubmitChanges, when the Update method gets called on the server, the Albums collection is null.
Does anyone have any suggestions, or can you point me to an example that uses more complex objects?
EDIT (keeping the above for posterity): Alright, it appears that the second issue (a reference to an entity or a collection of entities showing as null when Update gets called on the server) exists because the child entites aren't marked as Changed and so they aren't being serialized and sent back. I know you can force that to happen by using [Composition] and I have gotten it to work that way, but this is not a compositional relationship and I want both entities to be "top-level" entities. How can I mark an entity as changed?
The problem was that my [Association] attributes weren't correctly defined. I didn't realize that the association's Name property has to be the same on both sides of the association. When the names are the same and you do a build, the generated code on the client uses a different constructor for the EntityCollection used by the "parent" to refer to the "children" than it does if the associations aren't set up right. The new constructor takes callbacks that do a little bit of extra handling when you call Add and Remove on the collection - specifically, they take the child entity you are adding or removing and modify the property on it that refers to its parent so that everything remains in sync: the collection you removed the object from, the collection you added it to, and the object's reference to its parent.