Reputation: 11453
Just starting with CoreData and just wondering, how to create "complex" FetchRequest
. I have following data-structure (minified for question):
There are several books and several people (creators). Creators can be an author, translator, illustrator (...). Some "Creator" have several "roles", that`s why I ended up with the "CreatorBook-Entity", because sometimes the same creator has different roles for different books..
Anyway... In the app I show the Book
and there's a CollectionView with other Books
from the same Author (=Creator
with the role= Author
). I tried to create a FetchRequest
but didn`t know how to combine the different Entities, so at the moment I iterate through CoreData like the following:
//Get all Creators from Book and get the first Author
Creator* author;
NSSet* creatorSet = self.book.creator;
if( [creatorSet count] > 0 ){
for(CreatorBook *uObjects in creatorSet){
if([uObjects.role isEqualToString:@"Author"]){
author = uObjects.creator;
break; //get first author
}
}
}
//Get all the Book from the same Author
if(author != nil){
NSSet* authorBooks = author.book;
NSMutableArray* books = [[NSMutableArray alloc] init];
for(CreatorBook* object in authorBooks){
Book* a = object.book;
[books addObject:a];
}
_authorBookCollection = books;
[self.bookPreview reloadData];
}
Is there a way to get the same result with one FetchRequest
?
How can I get all Books
if there are more than one Author
? (my code above stops at the first)
Is it possible to fetch all Books
ordered by an attribute from Creator (for example the authors fullname (more than one author -> show book several times))?
Upvotes: 0
Views: 131
Reputation: 80273
First, your attribute name creator
for the Book entity is misleading. Potentially, a book has more than one creator, i.e. an author, illustrator, etc. So I used creators
(in the plural) to reflect the to-many relationship. Similarly, I renamed the to-many relationship from Creator to the join table books
.
Second, I am assuming that the book has only one author - or one creator with the same role. Of course, it is thinkable that this could be different (there is a solution for that case as well).
NSSet *creatorsOfThisBook = book.creators;
Creator *authorOfThisBook = [[creatorsOfThisBook filteredSetUsingPredicate:
[NSPredicate predicateWithFormat:@"role = %", @"author"]] anyObject];
NSSet *booksByThisAuthor = [[authorOfThisBook.books filteredSetUsingPredicate:
[NSPredicate predicateWithFormat:@"role = %", @"author"]]
valueForKeyPath:@"book"];
You can see that if a Creator is only an author, you could leave out the second predicate.
Upvotes: 0