Лучший способ обнаружить отношения динамически при сохранении новой записи?(otherSide не работает) - PullRequest
2 голосов
/ 29 апреля 2011

Учитывая эти отношения:

class A {
    String name
    static hasMany = [b:B]
}
class B {
    String name
    static belongsTo = [a:A]
}

У меня есть запись b, которую я хочу сохранить. Я уже обнаружил с помощью отражения Grails (опущено в примере кода ниже), что он должен быть экземпляром класса B. Помимо этого, запись b знает только:

  • имеет отношение "а"
  • отношение "а", ключ

Поскольку это динамический случай, мы не знаем и должны обнаружить:

  • отношение "a" относится к экземпляру класса A (поэтому мы можем назвать A .find (ключ a))
  • «другая сторона» отношения - точка зрения класса A - это отношение « b » (поэтому мы можем назвать .addToB (b))

Так как мне сохранить b в базе данных? Вот как я это делаю:

class AssocTests extends GrailsUnitTestCase {
    protected void setUp() {
        super.setUp()
        // I don't know this part, but it's in the DB
        def a = new A(name:"al")
        a.save()
    }

    void testAssociation() {
        // I want to create a new B such that name="bob"
        // I also had to discover "class B" using (working) Grails reflection
        // but omitted it for this example.
        def b = new B(name:"bob")
        // ... and the relation is as "given" below
        def given = [a:[name:"al"]]
        // So I need to call A.find([name:"al"]).addToB(b).  But "A" and
        // "addToB" are unknown so need to be found via reflection
        def gdc = new DefaultGrailsDomainClass(B)
        given.each { give ->
            def prop = gdc.getPropertyByName(give.key)
            if (prop.isAssociation() && !prop.isOwningSide()) {
                println "I want to use otherSide, but it's ${prop.otherSide}"
                def os = reallyGetOtherSide(B, give)
                def object = os.parent.find(
                        os.parent.newInstance(give.value))
                object."${os.method}"(b)
            }       
        }       
        def bFound = B.findByName("bob")
        assertEquals "al", bFound.a.name
    }

    def reallyGetOtherSide(clazz, relation) {
        def parent=clazz.belongsTo[relation.key] 
        def addTo=parent.hasMany.find { (clazz == it.value) }.key
        [parent:parent, method:"addTo${addTo.capitalize()}"]
    }
}

... с другой стороной, возвращающей ноль, к сожалению Это не может быть лучшим способом сделать это, не так ли?

1 Ответ

0 голосов
/ 29 апреля 2011

Если я вас правильно понял, вы можете обратиться к этим документам здесь .Вы можете попробовать следующее:

  `new A(name:"Gatwick")
         .addToB(new B(name:"BA3430"))
         .addToB(new B(name:"EZ0938"))
         .save()`
...