I have spent hours upon hours trying to figure out how to setup the models for object relationships and create/delete many-to-many relationships in Realm using Objective-C. The documentation has been less than helpful. I could use some guidance on whether to use RLMArray or RLMLinkingObjects... If I use RLMLinkingObjects to set up my to-many relationships, I cannot use addObject:
to create the relationships, and I cannot find any way to delete a relationship. I am moving from a Core Data relational database and have several many-to-many relationships that I am trying to model, and this just makes no sense at all to me. The only documentation showing a many-to-many relationship shows a class relating two of its own properties. One of the properties uses RLMArray and the other uses RLMLinkingObjects. This makes no sense to me, since a many-to-many relationship is supposed to be bi-directional, and relationships should be able to be added or deleted via either side. Maybe I am thinking about this wrongly, but I am lost and would appreciate some help.

- 4,078
- 7
- 41
- 77
-
1`RLMArray` is a unidirectional link to multiple objects, and `RLMLinkingObjects` is a unidirectional inverse link to the objects that are linking to the object. The relationship can be modified via the `RLMArray`, which will automatically manage its inverse relation (corresponding `RLMLinkingObjects`). If you need to modify the relationship from the target, then you can find the object with the `RLMArray` using a link query across the linking objects via primary key. – EpicPandaForce Jun 13 '17 at 23:58
-
At this point, could you possibly direct me to some code that demonstrates this? I am not trying to get someone to do my work for me - I truly have spent hours and researched it as thoroughly as I possibly can and do not understand how to set this all up. – SAHM Jun 14 '17 at 00:01
-
1...well, I'll try to put some snippets together from the docs. I'm not well-versed in anything iOS (especially if you see my post history and tags) – EpicPandaForce Jun 14 '17 at 00:02
-
I do appreciate it - but I've scoured the docs and this still doesn't make any sense to me. I guess I am just not grasping it. – SAHM Jun 14 '17 at 00:03
-
For a to-many, do we just randomly assign one end of the relationship as RLMArray and the other as RLMLinkingObjects? – SAHM Jun 14 '17 at 00:04
-
And even for a one-to-many, do we assign the list as RLMArray or RLMLinkingObjects? It seems there is a choice to be made, and it's just not clear how to go about making it. – SAHM Jun 14 '17 at 00:06
-
1Well pretty much, depending on which side points towards which side. The inverse is auto-managed. For example, you could model `dogs.owner` as the RLMArray, but you could also model `person.dogs` as such. And generally, `person.dogs` makes more sense. `RLMArray` is where you add what belongs to the object, and the linking ones are automatically managed if you add/remove anything to RLMArray. – EpicPandaForce Jun 14 '17 at 00:07
-
Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/146586/discussion-between-sahm-and-epicpandaforce). – SAHM Jun 14 '17 at 00:08
1 Answers
Many
relationships in Realm are modelled with RLMArray
. Every to-one and to-many relationship however creates its own corresponding inverse relationship, which is modelled by RLMLinkingObjects
(the objects that are linking to this current object).
So RLMArray
is a unidirectional link to multiple objects, and RLMLinkingObjects
is a unidirectional inverse link to the objects that are linking to the object. The relationship can be modified via the RLMArray
, which will automatically manage its inverse relation (corresponding RLMLinkingObjects
).
If you need to modify the relationship from the target, then you can find the object with the RLMArray
using a link query across the linking objects via primary key.
import <Realm/Realm.h>
@class Person;
// Dog model
@interface Dog : RLMObject
@property NSInteger id;
@property NSString *name;
@property (readonly) RLMLinkingObjects *owners;
@end
RLM_ARRAY_TYPE(Dog) // define RLMArray<Dog>
// Person model
@interface Person : RLMObject
@property NSInteger id;
@property NSString *name;
@property NSDate *birthdate;
@property RLMArray<Dog *><Dog> *dogs;
@end
RLM_ARRAY_TYPE(Person) // define RLMArray<Person>
// Implementations
@implementation Dog
+ (NSDictionary *)linkingObjectsProperties {
return @{
@"owners": [RLMPropertyDescriptor descriptorWithClass:Person.class propertyName:@"dogs"],
};
}
+ (NSString *)primaryKey {
return @"id";
}
+ (NSArray *)indexedProperties {
return @[@"name"];
}
@end
@implementation Person
+ (NSString *)primaryKey {
return @"id";
}
+ (NSArray *)indexedProperties {
return @[@"name"];
}
@end
So when you modify person.dogs
in a transaction, then dog.owners
will be automatically updated.
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
Person *jim = [[Person objectsWhere:@"name == 'Jim'"] firstObject];
// Jim is owner of Rex
Dog * rex = [[Dog objectsWhere:@"name == 'Rex'"] firstObject];
[jim.dogs addObject:rex]; // <-- now rex's `owners` contains `jim`
}];
You can read more about relationships in Realm here.

- 79,669
- 27
- 256
- 428
-
Can a dog have multiple owners in your example? Is this a many-to-many relationship you are modeling? – SAHM Jun 14 '17 at 00:22
-
1A person can have multiple dogs. Afterwards the dog doesn't really care whether it's one or many that's pointing to it, it's always modelled as linking objects which is 0..* – EpicPandaForce Jun 14 '17 at 00:23
-
I am just trying to figure out if this is how I model a many-to-many. So, if a dog can have multiple owners, that would help me understand. – SAHM Jun 14 '17 at 00:24
-
1`RLMLinkingObjects` is a list, so technically yes, in this model, a Dog can have multiple owners. It does **not** restrict it to 1 owner, that is for certain. – EpicPandaForce Jun 14 '17 at 00:24
-
So then this is the preferred way to model a many-to-many? If so, what would you change about it to model a many-to-one? For example, what would the code look like if a dog could only have one owner, but an owner could have multiple dogs? – SAHM Jun 14 '17 at 00:26
-
1Then the **Dog** would need to specify `Person *owner;` (NOT array because you said *one*), and then **Person** would have the `RLMLinkingObjects*` field called `dogs`. – EpicPandaForce Jun 14 '17 at 00:26
-
So the person would have RLMLinkingObjects for dogs and not RLMArray for dogs? Is this always the case? – SAHM Jun 14 '17 at 00:27
-
Oh, I thought it had to have one or the other, RLMArray or RLMLinkingObjects – SAHM Jun 14 '17 at 00:29
-
1`RLMArray*` models MANY links. `SomeObject*` models ONE links. `RLMLinkingObjects*` models INVERSE links. – EpicPandaForce Jun 14 '17 at 00:29
-
I get that (to some, limited extent, as you can see), but if I use Person *owner; on Dog, I can use only RLMArray or RLMLinkingObjects for dogs on Person - am I wrong? I am truly not trying to be obtuse (it just comes naturally). – SAHM Jun 14 '17 at 00:31
-
1Actually, then you can only use `RLMLinkingObjects*` for `dogs` field in `Person`, because it is the *inverse* link for `owner`. Well technically you *can* manage multiple links side-by-side, but it makes *your* life more complicated to have two links instead of one where the other direction is auto-managed. But this is all in the docs I linked at the bottom of the answer. – EpicPandaForce Jun 14 '17 at 00:32
-
But is this the case for every one-to-many inverse relationship? RLMLinkingObjects as opposed to RLMArray? I have read the docs, they just left me with many questions. – SAHM Jun 14 '17 at 00:33
-
1Every inverse relationship is modeled with `RLMLinkingObjects*`, yes. Because they are "the objects that are linking to this current object". – EpicPandaForce Jun 14 '17 at 00:34
-
1Okay, I will use Class name/RLMLinkingObjects for one-to-many inverse relationships, and RLMArray/RLMLinkingObjects for many-to-many inverse relationships. – SAHM Jun 14 '17 at 00:35
-