Nicolas M.
Nicolas M.

Reputation: 829

has many relationship through with Core Data

Let's say I have 3 models: Hotel, Category and Room. A hotel has many categories and a category has many rooms.

I want to get an array of all the room numbers for a specific hotel.

In Rails, with ActiveRecord I would have the following:

class Hotel
  has_many :categories
  has_many :rooms, through: :categories
end
class Category
  has_many :rooms
end

and then, if I have a hotel object, the query would be as simple as:

hotel.rooms.map(&:room_number)

And I would get an array of room numbers for the hotel.

How can I achieve the same thing with Objective-C and Core Data? Can MagicalRecord help with this type of abstraction? Do I have to write the SQL statement directly because the current ORMs don't support anything like this?

Thanks, Nicolas

Upvotes: 0

Views: 293

Answers (2)

Martin R
Martin R

Reputation: 540145

Assuming that the relationships are define like this:

enter image description here

you can use "Key-Value Coding" to get all room numbers for a given hotel:

Hotel *theHotel = ...;
NSSet *setOfRoomNumbers = [theHotel valueForKeyPath:@"[email protected]"];
// And if you need an array instead of a set:
NSArray *arrayOfRoomNumbers = [setOfRoomNumbers allObjects];

A disadvantage of this method is that it fetches all categories first and then the rooms.

Alternatively, you can execute a fetch request for the "Room" entity, using the inverse relationships:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Room"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"category.hotel == %@", theHotel];
request.predicate = predicate;
NSArray *rooms = [context executeFetchRequest:request error:&error];
NSArray *roomNumbers = [rooms valueForKey:@"roomNumber"];

With Magical Record, this would probably look like (untested):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"category.hotel == %@", theHotel];
NSArray *rooms = [Room MR_findAllWithPredicate:predicate];
NSArray *roomNumbers = [rooms valueForKey:@"roomNumber"];

Upvotes: 2

Arthur Shinkevich
Arthur Shinkevich

Reputation: 801

You don't need to write any SQL queries with Core Data and especially with Magical Record. Here is the link to a documentation on how to fetch objects and relationships.

A simple example would be this:

NSArray *rooms = @[@1, @2, @3, @4];
NSPredicate *roomFilter = [NSPredicate predicateWithFormat:@"Rooms IN %@", rooms];

NSArray *rooms = [Person MR_findAllWithPredicate:roomFilter];

This is just an example code, don't treat as a fully working and tested solution.

Upvotes: 0

Related Questions