Reputation: 5291
Since I have upgraded my Grails version the generated code in controller's save method has changed. I have gone through the documentation which explains each item separately but it would be great if someone can explain the request.withFormat
part holistically.
The following snippet is taken from an automatically generated Save
action. One thing that is puzzling me is. Which line here indicates, render "show" view after successful save operation?
def save(User userInstance) {
if (userInstance == null) {
notFound()
return
}
if (userInstance.hasErrors()) {
respond userInstance.errors, view:'create'
return
}
userInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [
message(code: 'user.label', default: 'User'),
userInstance.id
])
redirect userInstance
}
'*' { respond userInstance, [status: CREATED] }
}
}
Upvotes: 2
Views: 1966
Reputation: 1016
It seems that this is an undocumented behavior of redirect. But looking at grails code we can figure out that it uses this convention:
If redirect takes just a PERSISTED object as argument, it will infer the show action url and use the object id as the url argument.
There is a Jira for that doc issue at https://jira.grails.org/browse/GRAILS-11862
Some more resources on that:
http://grails.1312388.n4.nabble.com/New-controller-syntax-explained-td4654914.html
Regarding the withFormat snippet, it embraces three situations:
1) "form" A simple form submission excpecting an html response (enctype="application/x-www-form-urlencoded")
2) "multipartForm" A file upload form submission excpecting an html response (enctype="multipart/form-data")
3) "*" All other options, like json or xml in restfull requests
Situations 1 and 2 are handled by the same code.
Upvotes: 1
Reputation: 49542
request.withFOrmat
can be used to return different response types depending on the request accept header.
The example from the documentation:
request.withFormat {
html bookList:books // render html
js { render "alert('hello')" } // render javascript
xml { render books as XML } // render xml
}
In your example the controller can return two types of responses. One for multipart form requests and one that is used for all other requests:
request.withFormat {
form multipartForm {
// if it is a multipart form request -> add a flash message and redirect to another action
flash.message = message(code: 'default.created.message', args: [
message(code: 'user.label', default: 'User'),
userInstance.id
])
redirect userInstance
}
'*' {
// for all other request types, respond with the `userInstance` object
respond userInstance, [status: CREATED]
}
}
Upvotes: 3