user134611
user134611

Reputation: 776

Complex Core data relationship mess

need advice on a couple of entities and their relationships and the whole approach to it. Alot of core data tutorials and examples that are out there seem simple after a while when you actually attempt to make something real!..hence the question:

I need to know the approach and if what i've done is okay.. lets say a user creates his profile and starts organizing business cards. from the start, Lets say the app is capable of handling many users.

the Model: Entities:

1-User 2-CardGroup 3-Card 4-Entries

Now these are the four entities. User is the list of users added, each holding their own set of cards. THIS IS SIMPLY THE USER USING THE DEVICE(APP) NOT THE LIST OF PEOPLE ACTUAL BUSINESS CARDS ARE BEING STORED. For example, a user would be me, and Ive got a bunch of business cards lying around to organize in this app. this entity 'User' wouldnt not hold the names stamped on the business card,.. hope you get the point.

the entity Card, holds a list of business cards. This is the main one that actually holds the data to the card.

CardGroup, this is sorta the smart groups. A user can add categories to this like "Wallstreet" as one group, another could be "Silicon valley", their could be "UniversityMen" or just "Laydees".

Entries are This is kinda like a duplicates of a Card, lets say that guy had 5 different jobs over time, this entry just holds those aspects of the card that changed over time. A tracker so to speak..

I want to figure out the relationships here..

1- User <----------------->>CardGroup A user can have multiple groups for cards - Wallstreet, SiliconValley, MyCity, WorkPlace

2- CardGroup <------------>>CardDude Each cardGroup can hold a bunch of biz cards. A CardDude can be a part of WallStreet and/or MyCity, which is saying the same..? Also, Wallstreet can hold many cards. Im confused whther this is a many-to-many relationship or a one-to-many CardGroup <<------------->> CardDude

THis is making me realise that english isnt my first language.

3. A user can know only One CardDude right? Lets call em Jason, obviously there cant be many kinda Jasons.? Its gotta be just one. And cuz of that this relationship is User<---------------->CardDude one-to-one. Im not even sure here..

Also, If my dad is another user on this app (with his name in the first entity "User"), then he could potentially have his copy of CardDude Jason. Yea, im willing to do that for a reason. ahem.. So in the end, me and my dad both have their Jasons in CardDude. If i modify Jason as a User, then it should reflect on the other CardGroups like wallstreet, silicon but not on my dad's User entires, that should remain the same ( assuming he created one similar before).

Again, im not sure whats the relationship now.. User <------------------>CardDude

The pretext here is, when adding a carddude, this should happen only once for the USER and not let the USER add the same CARDUDE more than once, He could if a different USER is adding.

Heres the bigger puzzle, Now I wana add the latest info to that CardDude, Im callin it Entry. All it does is create a timeStamp, And add an entry of CardDude Jason, about a new card he may have had. a new job so to speak.

I'd want to see for every group.. in sql terms,

select ENTRY.name ENTRY WHERE USER = ME AND CARDGROUP = WALLSTREET

      I thot I'd have 
  CardGroup(WallStreet) <----------->>CardDude (Jason) and some more<----------->>Entry

WHERE, USER(me)<------------>CardDude(Jason)

 USER<-------------->>CardGroup to many
  USER<--------------->CardDude (onetoone)
  USER<--------------->>Entry (to many)

  CardGroup<------------>>CardDude
  CardDude<------------->>Entry (tomany) can tell me how many last cards did Jason get..

Please guide me on how to achieve a clear picture here, also Since Each USER can have only ONE Relationship with CardDude, how would i avoid putting in a duplicate similar entry.. Another point is, my dad's user would recreate the whole cardgroups, carddude and entries. they're quite independent.

THANKS GUYS, THIS is a looong question..

UPDATE: after the answer, I understood a lot of things, Now one thing remains, its they ideal way to get from CardGroup to CardEntry (which will include all CardPerson's) in that CardGroup... Right now Im just iterating through, but theres gotta be a better way to get all those CardEntries.

 //cardGroupFriends  is a CardGroup object        
  for(CardPerson *person in [cardGroupFriends persons]){
             for(CardEntry *entry  in [person entries]){
                 NSLog(@"%@ = %@", person.name, entry.company);
             }
         }

I just can't help but approach this via the sqlite route.. but I'm getting to like core data! It actually made things pretty simple., I was thinking about NSFetchedResultsController to fetch CardEntries from CardGroups, bypassing CardPerson entity (assuming I'm fetching all CardPersons in CardGroups) and fetch CardEntries using a timeStamp as sort order.

And for my understanding.. when Im adding a new CardEntry, I'm just using

[cardPerson addCardEntryObject:newEntry];

Is it understood that this "newEntry" is part CardPerson-->then CardGroup-->Current -User?? Assuming a User was selected at app launch and cardGroups are derived from there? Does core data take care of that? I don't want this newEntry to show up when the app switched User and selected the same CardPerson! Really appreciate your help

Upvotes: 0

Views: 1008

Answers (1)

Matthias Bauch
Matthias Bauch

Reputation: 90117

First of all.

I'd want to see for every group.. in sql terms,

stop doing that. Core Data is not sql.


Your Core Data Model is actually not very complicated. You are probably over-thinking it.

If I create a core data model it helps me to think in real world terms.

So you have a user (who uses his own physical card box). This box has groups (plural! = to-many). But each group is only in a single card box (reverse relationship to a single user).
Each of this groups has many people (plural). Next thing is not possible in the real world card box, but each person can be in many groups (reverse relationship, to-many).
And finally, you want to store more than one (to-many) business card. But each business card can only belong to one person (reverse relationship, single)

And you end up with something like this:

enter image description here


So how to avoid duplicate entries of CardPersons?

Manually.
Usually you don't have enough information of a business contact to distinguish people with the same name.
Maybe you know two people with the name Jason Smith. On of them is a iOS-Developer the other one a farmer. You probably don't want to store them as the same person.
But most likely you don't know much about the person. You know their first and last name. And usually that's it. If you would know for example the birthdate and the place of birth you could distinguish those two people automatically. But since you don't have those information you have to ask the user if the new business card belongs to the existing user named Jason Smith.

Upvotes: 1

Related Questions