Issues posting nested resource in Grails

孤街浪徒 提交于 2019-12-05 06:48:52

I think you can accomplish what you want by overriding the createResource() method.

@Override
protected Bid createResource() {

    Bid bid=super.createResource();
    bid.item=Item.get(params.itemId)
    return bid;
}

The other default controller actions will probably not work as expected when using nested URLs. You may also want to override queryForResource and index if you want to ensure that you only return Bids that belong to the item in the URL

@Override
protected Stay queryForResource(Serializable id) {
    def itemId=params.itemId

    Bid.where {
        id==id &&  item.id == itemId
    }.find()

}

def index(Integer max) {
    params.max = Math.min(max ?: 10, 100)
    def itemId=params.itemId
    respond Bid.where {
        item.id==itemId
    }.list(params)
}

The implementation of RestfulController has a method getObjectToBind() which returns the request object. I would suggest to override this method and give back a map that contains the key itemId as described in the comment of this method.

The other alternative could be, to send the itemId in the http json body. This is a little redundant, because the information are already represented in the url. But as a workaround, this could also be a good solution.

I recommend annotating the Domain classes with @Resource even if you implement your own controller. The Grails documentation seems to indicate you do one or the other, annotate the domain or write your own controller extending the RestfulContoroller.

I found that without the domain class annotation, the request object was not bound correctly in the createResource() method. All the properties were null. As soon as I added the domain annotation back binding happened as I expected.

In your case, I expect/hope Grails will handle all the relationships without you needing to manage the item id yourself. So,

@Resource(uri='items')
class Item {
    static hasMany = [bids:Bid]
}

and...

@Resource(uri='bids')
class Bid {
    Integer ownerId
    Double amount

    static belongsTo = [item:Item]

    static constraints = {
        ownerId nullable: false
        amount nullable: false
    }
}

Hopefully you won't need to override the getObjectToBind() any longer.

class BidController extends RestfulController<Bid> {
    static responseFormats = ['json', 'xml']
    BidController() {
        super(Bid)
    }
    //don't override the getObjectTobind
}

This worked for me when I was trying to post an object with a one-to-one mapping to another object.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!