簡體   English   中英

Grails數據綁定一對多關系

[英]Grails data binding one-to-many relationship

我正在嘗試利用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')
    }
}

當通過網站創建一個新的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個對象。

有人看到過這種行為嗎?

至少目前是Grails 1.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
}

我想知道是否正在發生以下情況:

當傳遞params [routes:""] ,框架將忽略它,因為它只是一個空字符串。

同樣, <input type="hidden" name="routes[0].latitude" value="5" />可能只是更新集合中的第零個路由條目,其他的不會被刪除,因為您所知道的是第零條路線的緯度值應為5,而不是現在應該是集合中的唯一路線。

為了獲得想要的效果,您需要在綁定參數之前添加routes.clear()

要控制何時將模型狀態持久化到數據庫中,可以使用Grails中可用的Spring事務性 如果后續處理失敗,這將允許您還原到對象的原始狀態。 例如:

Courier.withTransaction {status ->

  // Load the courier

  //clear the existing routes

  // bind the new properties

  // perform extra processing

  //if the object is invalid, roll back the changes
  status.setRollbackOnly()

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM