xxtesaxx xxtesaxx - 6 months ago 46
Swift Question

Filtering many-to-many relation by comparing objects agains keypath of objects in array with NSPredicate in swift

I hope you can help me. I'm building a Mac OS X App using Realm as the underlaying database system.

My model looks like this:

-Brick: a text brick consisting of the properties title and text

-GeneratorBrick: a many-to-many relation object for modeling the relation between Generator, Brick and some other data which is not relevant to the problem. Property on this object is called "brick"

-Generator: a configuration consisting of some text as well as a list of GeneratorBricks whose property name is "generatorBricks"

In my App, I now have a Generator object. This one holds a list to a bunch of GeneratorBrick objects which themselves each have a Brick and some other data. I display them in a TableView. I now want to display another TableView in which I only show those Brick objects which are not in the TableView of the current Generator. Bricks in the generator i access by

generator.generatorBricks[index].brick


In an earlier version of my App I loaded all the Brick objects I needed via
var bricks: Results<Brick> = try! Realm().objects(Brick).sorted("title").filter("inGenerator = false")
but since my model changed from using a property "inGenerator" to using another model class "GeneratorBrick" I need another way to filter. Unfortunately I have no idea how to accomplish this task. I tried different predicates like
generatorBricks IN %@", generator.generatorBricks
where the property "generatorBricks" is a backlink property in the Brick class.

Maybe I'm trying something which cannot be accomplished by using a predicate or maybe I just have not enough experience with predicates. Maybe I'm blind because I'm more used to plain SQL where I would use something like the following:

create table brick (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title varchar(255)
);
create table generator (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title varchar(255)
);

create table generatorbrick (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
brickId INT(6),
generatorId INT(6)
)

select * from brick b join generatorbrick gb on b.id = gb.brickid where gb.generatorid is not 123


Do you understandy my problem? Do you need additional information? I'm glad to provide if you can give me a hint into the right direction. Thank you in advance.

Answer

I came to the conclusion that what I want to do is not simply achievable with graph based Realm. At least not without loading all the bricks, generatorbricks and the generator and do a manually comparison by iterating over all the bricks and check if they are part of the current generator.

I would have needed something like

SELECT brick.* FROM brick JOIN generatorbrick on brick.id = generatorbrick.brickId JOIN generator on generator.id = generatorbrick.generatorId WHERE generator.id != 123