Many-to-Many relationships - ios

I have following entities with a many-to-many relationships.
i'm making a small playlist app where the entity named Entity is for the playlists and the songs entity is for the songs. at the moment i have a viewcontroller where you can add playlists to the Entity and a viewcontroller where you can add songs to the song entity. The problem is that all the videos are shown in every playlists. How can i hook this relationship up between these 2 entities?
Do i need to make a attribute in Songs which hold a playlist id? or how will the Entity know which song belong in which Entity object?

First of all, I would suggest to choose slightly different names for the entities
and relationships, in particular the singular form (Song, Playlist) for the entity
name, and the plural form of the destination (songs, playlists) for to-many relationships:
Now the objects are "hooked up" by setting the relationship between them.
Assume that you have a song and a playlist:
Song *songA;
Playlist *playlistB;
Now you can either call
[songA addPlaylistsObject:playlistB]; // (1)
or
[playlistB addSongsObject:songA]; // (2)
to establish a relationship between these two objects.
It does not matter whether which one you call because "songs" and "playlists"
are inverse relationships. songA is added to playlistB.songs,
and playlistB is added to songA.playlists.

Check this
This is picture of the answer! You will need to use a table to couple the to tables together.

Related

how to inset a new object in CoreDta and reflect the change in the relationship between two entities?

in my IOS10, swift 3, xcode8 application, I have Movie in coreData.
Movie: {id:Int32, name:String, genre: [ {Genre} ] }
Genre: {id:Int32, name:String}
the way I did it, is by creating a movie entity, and a genre entity, and set up many-to-many relationship between them...
is this correct ? cause one movie can have many genres, like action, comedy
and a genre, like romantic, can be associated with many movies.
my second question is, when I am saving a new movie to CoreData, How will the Genre entity know what happened, is there like a CoreData Feature that will do that automatically? or I should add a movie to the genre Set, and add a genre set for movie ?
my end goal is to be able to search for movies by titles, or by genre.
This is fairly basic, so I would recommend researching it: CoreData Documentation
But a basic rundown is when you create a many<->many relationship CoreData creates a connections table between the two models. The way coreData works is with managed objects, meaning every time you try and access an attribute of an NSManagedObject it will be the value in the saved database.
When you add something to a many-many relationship, the connections table will create the connection, and when access it from either model, the results will be based on that connections table.
TLDR, in CoreData if you have a relationship between two models, you only need to add the connection to one of the models.

Core Data - Relations queries

In core data,
I want to use relationship. But I have a doubt in my mind. Apologies but I didn't find clear answers on various websites and blogs. Other things like Add, Fetch, Delete queries are clear to me. But I have some questions in core data which are still not clear.
I have made two Entities:
Photographer [Attributes : name and camera]
Photo [Attributes: zoner and photographerName] .
1) I have connected them with relations. So if I connect this two entities with relations then I should remove that photographerName from Photo?
2) As I have connected these two entities with the relation then how can I use the photographer name with the photo Entity?
3) How can I add values in this if I use it with relations? [Now it is showing me Null in the relation from sqlite browser]
So if I connect this two entities with relations then I should remove that PhotographerName from Photo ?
Generally, yes, it is redundant.
how can I use the photographer name with the photo Entity ?
self.photographer.name
(assuming you are in the Photo class and the relationship names is photographer)
How can I add values in this if I use it with relations
I guess you mean how can I set the relationship value. Create an instance (or find an existing instance) or each entity and then:
photo.photographer = photographer;
Notes:
Ensure that the relationship has an inverse
Names the relationship ends photographer and photos (1 to many)
Try to set the photographer of a photo, or use the relationship methods auto-generated in the Photographer class to add photos

Nesting Issue In Core Data

I have created a database in which I have to store contacts in various categories. The issue comes when I have to create Sub categories in a Category like :-
Categories ->
Sub Categories->
Contacts
But the Categories can also have Contacts like
Categories -> Contacts
where the sub categories can also have contacts. I figured that nesting in core data would be used. How can I achieve this kind of a relationship ? How do I save the sub categories into the categories even though they are of the same entity ?
I have attached my core data entity relationship model here :-
There is no problem creating a "self" referencing relationship in CoreDate.
In other words, An entity may have a relationship of its own kind.
The only difference in your case between a Category and a SubCategory is the existence of a parent entity.
So there is no need to define a new entity for that part.
You can simply define a relationship:
Category.parent of type Category (say to-one in this case)
and a reverse relationship of:
Category.subCategories of type NSSet (to-many in this case) containing Category objects.
You can set all that up in your interface builder.
Now, since Category has a relationship with Contact so does all the "sub-categories" will have that relationship.
If you like your "sub-categories" to have additional properties, simply create a new entity an make it inherit from your Category entity (keeping the above setting I described).
and add to it the new properties.

Core Data - Order of objects in a to-many relationship

My app is a music library app, the user has their songs, and they can create playlists.
I want the order of the songs in the playlist to be in the order that the user adds those songs to that playlist.
My core data objects:
Song
=====
name
duration
album
artist (to one relationship)
Playlist
========
title
songs (to many relationship)
I have a tableview of playlists, each row in that table shows the title of the playlist and the name of the last song added to that playlist.
I have two questions:
How can i know what was the last song the user added to the playlist? even more how can I know the order of the songs in a given playlist?
How should I fetch that last song name when i'm building the playlists tableview?
Set the relationship type to ordered in the core data editor. This will mean that you now get an NSOrderedSet of songs instead of just an NSSet of songs
You could model the order explicitly by adding a new entity to the data model.
PlaylistOrder
=============
index (an integer of some type)
playlist (to one relationship)
song (to one relationship)
When you fetch PlaylistOrder managed objects, filter by playlist title, and sort by index.
Why not just add the index attribute to the Song entity? Presumably, a single song could belong to multiple playlists.
Ordered relationships are expensive. Expensive enough that they should be avoided unless there is simply no other way to sort the data. In your case, there is another way to sort the data.
If you add a insertedAt or createdAt property to your Song entity you now have something you can sort off of and get the order of the songs. That will be faster and perform better than using an ordered relationship. This becomes more apparent as you collect more data.
From there you can sort the Song entities on that new property and even build a convenience method in Playlist entity to determine what the last Song was (sort by date property, grab the last object).
Update 1
Since a song can be in multiple playlists then you could create a meta object between playlist and song. Effectively a join table with data in it:
Playlist <<--> SongMeta <-->> Song
The SongMeta entity would have createdAt as a property and then it gives you a place to add additional information about the song in that playlist. I have seen this design in music applications in the past.
However, if you foresee a user's ability to arbitrarily re-arrange the playlist then that definitely does fall within the ordered relationship's narrow useful scope. Just be mindful of the performance cost associated with it.

How to have repeated items in an Ordered To-Many relationship?

In Core Data of Xcode 4.3.2, an Ordered To-Many relationship is modelled with NSOrderedSet. It works well until I found the need to have repeated items in the relationship; it should really be modelled in a NSArray.
For example, in a music app, I have the following songs: SongA, SongB, SongC ,
I may want a party play list where people insert songs in any order and could be repeated. The list may look something like:
[SongC, SongC, SongA, SongC]
The way Core Data currently works, the list would become:
[SongC, SongA]
I.e., all repeated items are dropped, as it is modelled with sets.
So, coming back to my question: what is a good way to model repeated items in order in a relationship in Core Data?
Relationships are sets (and ordered relationships are ordered sets, but still sets); sets by definition contain unique objects. So you can't put duplicate objects into a relationship either way.
Whether you use the ordered-relation feature or not, you'll want to go back to the abstract ER model to find another way to turn your conceptual relationships into a Core Data model... it might help to think about how you'd do it in a plain SQL (or SQL-like) database and then come back to what Core Data does beyond SQL.
It sounds like you're making something akin to iTunes playlists, no? A model that might work for that would go something like:
Playlist <--->> PlaylistEntry
PlaylistEntry <<---> Song
The PlaylistEntry entity represents one instance of a Song's inclusion in one Playlist. You can have multiple PlaylistEntrys that reference the same Song in a single Playlist, and you can add other attributes to the PlaylistEntry to keep track of other things (like song order, if you're not using an ordered relationship). As a bonus, you can use that to add other features if you like -- say, to make a playlist that plays three different snippets out of one long track.
As rickster said, relationships as managed by Core Data uniquely associate entities between them. Even if Lion's Core Data (is supposed to) supports ordered relationships (supposed to, because in practice it won't work, the feature is buggy, barely usable), they still are relationships that follow the relational database model.
And so you have to manage the association by yourself, and you most certainly have to manage the ordered part of the association by yourself too.
Score <->> ScoreSong
ScoreSong <<-> Song
With ScoreSong having the following properties:
ScoreSong:
- score: -> Score
- song: -> Song
- order: integer, indexed
Then you have to use a Fetch Request with a sort descriptor for the key order, which will return an ordered NSArray of ScoreSong. You can ask the fetch request to prefetch the songs, then you can create the songs array, still properly ordered, with a single call to valueForKey: #"song".
Of course you have to create different ScoreSong for a single Song when you need to include than song more than once in your Score. That's the whole point of the added indirection.

Resources