Search code examples
iosswiftswift3realm

Filtering realm on pivot table relationship


Using realm I have setup 2 objects: User and Question.

Each User answers a Question, this is stored in a third object like so:

class Answer : Object {
    dynamic var user: User?
    dynamic var question: Question?
    dynamic var answerText = ""
}

What I need to do, is given a user object and a question object, get the related Answer object. In semi-SQL pseudo-code something like:

SELECT FROM Answers WHERE user = User and question = Question

 

So...How do I achieve this?

 


 

Bonus points if there is a way of not having to fetch the question object and instead use the primary key of that object (i have the user object, but only a question id, so i have to resolve the question object first), so something like:

SELECT FROM Answers WHERE user = User and question.id = Question.id

Also because realm doesn't load the entire object into memory until you need it, I don't think it's capable of that.

Note: I've simplified by problem a little. There is a good reason I have the no primary answer id, so please don't tell me to add one.


Solution

  • You will need to change your User model to include an inverse relationship with Answer. This will automatically include all answers where user equals the current user.

    Then you will need to query the users, access their answers property and filter that based on the questions.

    I have created these skeleton classes so that I can test the query, I know that your User and Question class might be different, so change the primaryKey and question filter to suit your exact class definition.

    class User: Object {
        let answers = LinkingObjects(fromType: Answer.self, property: "user")
        dynamic var userName = ""
        override class func primaryKey()->String {
            return "userName"
        }
    }
    
    class Answer : Object {
        dynamic var user: User?
        dynamic var question: Question?
        dynamic var answerText = ""
    }
    
    class Question: Object {
        dynamic var title = ""
    }
    
    let questionId = ""
    let questions = realm.object(ofType: User.self, forPrimaryKey: "userName")?.answers.filter("question.id = %@",questionId)