Reputation: 651
This issue may have be raised here before, but I am not confident that I have understood the solution. Here is the problem, in Objective-C, Core Data, for iOS.
I am going to model a twitter-like User-Following relationship, One user can follow many, and be followed by many. The Following itself has attributes such as createTime, pending, and level - that means, I cannot merely let User has bidirectional relationships like follower and followed, like :
User <<->> User
but add one more entity, Following, with relationships like following and followed.
User <->> Following <<-> User
Here are two questions:
Is this the best practice?
If so, how to write a [aUser valueForKeyPath: ...]; to fetch his/her followers or friends (being followed).
Upvotes: 2
Views: 564
Reputation: 1448
I found a great example of what you were trying to accomplish here, and thought I'd share. Check here under the "Many-to-Many Relationships" heading. You should find an example using a Person entity and a FriendInfo entity that describes the pattern you're using in more detail.
Note: The link is to the "Relationships and Fetched Properties" section of Apple's Core Data Programming Guide, which may or may not be available to those without an Apple Developer's account, and of course is subject to change.
Upvotes: 0
Reputation: 124997
Is this the best practice?
I don't think this problem falls into the category of "situations for which a best practice has been established", but it seems like a reasonable solution.
If so, how to write a [aUser valueForKeyPath: ...]; to fetch his/her followers or friends (being followed).
Let's say that Following
has a follower
property for the person doing the following, and a leader
property for the person being followed. Also, User
has a leads
property for the Following
relationships with people who follow a user and a follows
property for the Following
relationships with people that the user follows. Finally, User
also has a name
property.
Given all that, to get the names of aUser's followers, you could say:
NSSet *followers = [aUser valueForKeyPath:@"leads.follower.name"];
and to get the names of people aUser follows:
NSSet *leaders = [aUser valueForKeyPath:@"follows.leader.name"];
It seems a little odd at first that you'd get sets back from those key paths since the last two keys in each path are singular. However, since the leads
property returns a set of Following
objects, leads.follower
returns a set containing the users for each of those objects, and leads.follower.name
returns a set containing the names of the users of those objects.
Upvotes: 2