1対多の関連付けのデータバインディングを処理するGrailsの機能を利用しようとしています。リレーションシップに正常に割り当てることはできますが、単一の要素またはすべての要素を削除しても機能しません。
これが私のモデルがどのように見えるかの例です:
class Location {
Float latitude
Float longitude
}
class Route {
Location start
Location stop
static belongsTo: [courier: Courier]
}
class Courier {
String name
static hasMany = [pickups: Location]
}
class ScheduledCourier extends Courier {
static hasMany = [routes: Route]
static mapping = {
routes(cascade: 'all-delete-orphan')
}
}
Webサイトを介して新しいScheduledCourierオブジェクトを作成する場合、次のようにマークアップで自動的にバインドするルートのリストを渡すことができます。
<input type="hidden" name="routes[0].latitude" value="5" />
<input type="hidden" name="routes[0].longitude" value="5" />
<input type="hidden" name="routes[1].latitude" value="10" />
<input type="hidden" name="routes[1].longitude" value="10" />
これは私のコントローラーでうまく機能します:
class CourierController {
// Very simplistic save
def saveScheduled = {
def courier = new ScheduledCourier(params)
courier.save()
}
// Very simplistic update
def update = {
def courier = Courier.get(params.id)
courier.properties = params
courier.save()
}
}
代わりに次のマークアップを使用すると、デバッガーをステップスルーして、routesプロパティが[]になり、オブジェクトは正常に保存されますが、レコードはデータベースから削除されないことがわかります。
<input type="hidden" name="routes" value="" />
さらに、次のようなマークアップを送信した場合:
<input type="hidden" name="routes[0].latitude" value="5" />
<input type="hidden" name="routes[0].longitude" value="5" />
courier.routesは、1つのオブジェクトのみを含むように更新されません。
誰かがこの行動を見たことがありますか?
これはGrails1.3.7です...少なくとも今のところは。
この動作を再現する統合テストを作成しました。
public void testCourierSave() {
def l1 = new Location(latitude: 5, longitude: 5).save(flush: true)
def l2 = new Location(latitude: 10, longitude: 10).save(flush: true)
def params = ["name": "Courier", "pickups[0].id": l1.id, "pickups[1].id": l2.id,
"routes[0].start.id": l1.id, "routes[0].stop.id": l2.id,
"routes[1].start.id": l2.id, "routes[1].stop.id": l1.id]
def c1 = new ScheduledCourier(params).save(flush: true)
assertEquals(2, c1.routes.size())
params = [routes: ""]
c1.properties = params
c1.save(flush: true)
c1.refresh() // Since the Routes aren't deleted, this reloads them
assertEquals(0, c1.routes.size()) // Fails
assertEquals([], Route.findAllByCourier(c1)) // Fails if previous assert is removed
}