Raj Pawan Gumdal
Raj Pawan Gumdal

Reputation: 7438

Coredata NSFetchedResultsController predicate on One-To-Many relationship (outside in)

I have a the following setup in my coredata xcdatamodel:

enter image description here

Basically there are a set of Articles (TMArticle) in the website which will be categorised into Sections (TMSection) and Journals (TMJournal). The app navigation would have to display all sections first and then navigate to display only a list of journals which are contained in all articles belonging to the selected section. I am not quite sure as to how I can accomplish this without an inverse relationship. Ideally speaking in this setup there is no need for inverse relationship (from section and journal back to Articles), but how can I write a predicate which does exactly what I seek for?

I get list of all articles using the following FRC:

@synthesize articlesFRC = articlesFRC_;
-(NSFetchedResultsController*)articlesFRC {
    if (nil==articlesFRC_) {
        NSFetchRequest *articlesFR = [NSFetchRequest fetchRequestWithEntityName:[TMArticle entityName]];
        NSSortDescriptor *articleSD = [NSSortDescriptor sortDescriptorWithKey:@"nid"
                                                                    ascending:NO];
        [articlesFR setSortDescriptors:[NSArray arrayWithObject:articleSD]];
        articlesFRC_ = [[NSFetchedResultsController alloc] initWithFetchRequest:articlesFR
                                                           managedObjectContext:[[[RKObjectManager sharedManager] objectStore] managedObjectContextForCurrentThread]
                                                             sectionNameKeyPath:nil
                                                                      cacheName:nil];
        [articlesFRC_ setDelegate:self];
        [articlesFRC_ performFetch:NULL];
    }
    return articlesFRC_;
}

However, I am stuck at creation of FRC for fetching only those journals which belong to articles for which the user has already selected a section, placeholder predicate for my FRC:

@synthesize journalsFRC = journalsFRC_;
-(NSFetchedResultsController*)journalsFRC {
    if (nil==journalsFRC_ && nil!=self.selectedSectionManagedObjectID) {
        NSFetchRequest *journalFR = [NSFetchRequest fetchRequestWithEntityName:[TMJournal entityName]];
        NSSortDescriptor *journalSD = [NSSortDescriptor sortDescriptorWithKey:@"weight"
                                                                    ascending:YES];
        [journalFR setSortDescriptors:[NSArray arrayWithObject:journalSD]];
        [journalFR setPredicate:<#(NSPredicate * _Nullable)#>];
        journalsFRC_ = [[NSFetchedResultsController alloc] initWithFetchRequest:journalFR
                                                           managedObjectContext:[[[RKObjectManager sharedManager] objectStore] managedObjectContextForCurrentThread]
                                                             sectionNameKeyPath:nil
                                                                      cacheName:nil];
        [journalsFRC_ setDelegate:self];
        [journalsFRC_ performFetch:NULL];
    }
    return journalsFRC_;
}

I also would want to ensure that any changes to selection of section or an update in list of articles through webservice call should automatically update the list of Journals which satisfy the condition, I am not quite sure as to how I can accommodate the same in the predicate above.

Additional Info:

Forgot to mention earlier that taxonomyID is the primary key for both Sections (TMSection) and Journals (TMJournal), while nid is the primary key for articles (TMArticle).

A sample webservice response for each:

Article list:

[
    {
        "nid": "3",
        "listing_post_date": "Tuesday, August 15, 2017 - 19:49",
        "listing_updated_date": "Tuesday, August 15, 2017 - 19:49",
        "title": "ACL Tear",
        "field_journal": [
            {
                "tid": "6"
            },
            {
                "tid": "7"
            }
        ],
        "field_section": [
            {
                "tid": "2"
            },
            {
                "tid": "8"
            }
        ]
    },
    {
        "nid": "1",
        "listing_post_date": "Saturday, March 25, 2017 - 14:23",
        "listing_updated_date": "Sunday, April 9, 2017 - 10:51",
        "title": "Reverse Total Shoulder arthroplasty",
        "field_journal": [
            {
                "tid": "3"
            },
            {
                "tid": "4"
            }
        ],
        "field_section": [
            {
                "tid": "2"
            },
            {
                "tid": "5"
            }
        ]
    }
]

Section list:

[
    {
        "name": "Sports",
        "field_section_image": [],
        "tid": "2",
        "weight": "0",
        "field_section_color": {
            "rgb": "#bbf1f3"
        }
    },
    {
        "name": "Hand",
        "field_section_image": [],
        "tid": "5",
        "weight": "1",
        "field_section_color": {
            "rgb": "#96c394"
        }
    },
    {
        "name": "Knee",
        "field_section_image": [],
        "tid": "8",
        "weight": "2",
        "field_section_color": {
            "rgb": "#f29d9d"
        }
    }
]

Journal list:

[
    {
        "name": "Bone &amp; Joint Research",
        "tid": "3",
        "weight": "0"
    },
    {
        "name": "Sports Journal",
        "tid": "7",
        "weight": "0"
    },
    {
        "name": "Sports Medicine",
        "tid": "4",
        "weight": "0"
    },
    {
        "name": "The Knee Journal",
        "tid": "6",
        "weight": "0"
    }
]

Upvotes: 1

Views: 203

Answers (1)

pbasdf
pbasdf

Reputation: 21536

You should almost always specify inverses for every relationship; there are very few situations where you are better off without.

Looking at your data, it seems that a given section can be related to many articles, so add a to-many relationship from TMSection to TMArticle.

The data only has journals being related to one article; if that is universally true then you can add a to-one relationship from TMJournal to TMArticle.

Then use the following predicate to fetch TMJournals:

[journalFR setPredicate:[NSPredicate predicateWithFormat:@"ANY article.sections == %@", self.selectedSectionManagedObjectID];

Sadly the FRC will only observe changes to the Journal objects, so you will need to specifically handle changes to either the Articles or the selection Section.

Upvotes: 2

Related Questions