#grails #dynamic #grails-orm #one-to-many
#grails #динамический #grails-orm #один ко многим
Вопрос:
Учитывая эту взаимосвязь:
class A {
String name
static hasMany = [b:B]
}
class B {
String name
static belongsTo = [a:A]
}
У меня есть запись b, которую я хочу сохранить. Я уже обнаружил с помощью рабочего отражения Grails (опущенного в примере кода ниже), что это должен быть экземпляр класса B. Помимо этого, запись b знает только:
- у него есть отношение «a»
- ключ отношения «a»
Поскольку это динамический случай, мы не знаем и должны обнаружить:
- отношение «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() amp;amp; !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()}"]
}
}
… к сожалению, на другой стороне возвращается значение null. Это не может быть лучшим способом сделать это, не так ли?
Ответ №1:
Если я вас правильно понял, вы можете обратиться к этим документам здесь. Вы можете попробовать следующее:
`new A(name:"Gatwick")
.addToB(new B(name:"BA3430"))
.addToB(new B(name:"EZ0938"))
.save()`
Комментарии:
1. Я думаю, что это недоразумение. Это динамический случай, когда я не знаю об «A.addToB» и должен обнаружить его путем отражения. Кроме того, я не создаю новый A. Представьте, что у меня есть некоторые другие классы и отношения, которые я опустил для краткости. Тем не менее, спасибо за ответ.