Find all objects with value in list

2019-09-10 07:05发布

I'm introducing myself to the Grails environment (It's awesome). I've been reaping the benefits of dynamically generated methods like the findAllBy* range. However, I've come to a problem and I'm unsure about how to proceed. An hour spent on Google didn't yield all that much for me either.

Problem

I have a class like the following:

class Runner {

    static hasMany = [owners: Owner]
}

And in my Owner controller, I wish to find all Runner objects, that contain a given Owner. Effectively, I'm trying to go from the many to the one.

Example

If I have an Owner object, that looks something like

Owner[name="Dave"]

And I have a Runner with something like:

Runner[owners[Owner[name="Dave"], Owner[name="James"]]]

My query should return this Runner object, but it should not return

Runner[owners[Owner[name="Bill"], Owner[name="James"]]]

My attempts

I've attempted to use the inList extension, but after some further research I realised that was designed for the other way around. My code at the moment is as follows:

def runners() {
    log.info("Runners")
    List<Runner> runners;
    Owner owner;

    if (params.id) {
        log.info("Id = " + params.id);
        owner = Owner.get(params.id);
        log.info("owner = " + owner.name);
        // Grab runners in list thing.
        log.info("Number of results = " + runners.size());
    }


    [results: results, jockeyInstance: jockey]
}

标签: grails gorm
3条回答
冷血范
2楼-- · 2019-09-10 07:20

Is this something you are expecting?

def results = Runner.withCriteria {
    owners {
        eq 'name', 'Dave'
        //idEq params.id //If id of owner is provided
    }
}

assuming you have

class Runner {
    static hasMany = [owners: Owner]
}

class Owner {
    String name
}

Here is a sample you can try.

查看更多
甜甜的少女心
3楼-- · 2019-09-10 07:23

maybe not the answer for the question at hand, but you could also make the runners known to the owners like this

    class Runner {
            String name
            static hasMany = [ owners: Owner ]
            static belongsTo = Owner
    }


    class Owner {
            String name
            static hasMany = [ runners: Runner ]
    }

    Owner o1 = new Owner(name: "O1").save()
    Owner o2 = new Owner(name: "O2").save()
    Owner o3 = new Owner(name: "O3").save()
    new Runner(name: "R1").with{
            addToOwners(o1)
            addToOwners(o2)
            save()
    }
    new Runner(name: "R2").with{
            addToOwners(o1)
            addToOwners(o3)
            save()
    }
    print o3.runners

results in [runnerowner.Runner : 2]

查看更多
萌系小妹纸
4楼-- · 2019-09-10 07:30

After some research into HQL, I found a more elegant solution that didn't require me to change the Domain classes at all. The query I used was as follows:

runners = Runner.executeQuery("FROM Runner as r WHERE :owner in elements(r.owners)", [owner : ownerInstance]);

Where ownerInstance is the Owner object being used to map to the Runner.

查看更多
登录 后发表回答