Closed bodiam closed 9 years ago
Is the problem only with the respond
method or do you see the same behavior if you return a Map
as the model? Does the problem have anything to do with command objects?
I am trying to recreate the problem. I have tried the following:
// grails-app/controllers/demo/DemoController.groovy
package demo
class DemoController {
def showWidget(Widget widget) {
[widget: widget]
}
def respondWithWidget(Widget widget) {
respond widget
}
}
class Widget {
String name
}
I expect there is some other piece of the puzzle that is relevant. Can you create a simple sample app which demonstrates the problem, push that to a public github repo and provide a link here?
Thanks for your feedback.
I see now that I can recreate the problem if I do something like this instead of using a command object...
respond new Widget(params)
Will investigate.
Yeah, the respond is indeed the relevant part, sorry if I wasn't clear on that!
The problem here doesn't have anything to do with respond
or passing command objects to the view. The problem is that you are passing a Map
as an argument to the constructor of your Registration
class. That class doesn't have a property named controller
but the Map
you are passing does contain a controller
entry. The MissingPropertyException is standard Groovy behavior. If you just do def foo = new Registration(params)
I think you will see the same behavior. Domain classes have a special constructor which ignore extra entries in the Map
. Registration
apparently is not a domain class.
It isn't clear why you are creating the Registration
yourself, but you should be able to do something like this...
def index(Registration r) {
respond r
}
Yeah, the respond is indeed the relevant part
I don't think that is correct. See my comments above. Can you confirm, or is there another piece of this that I am missing.
Thanks for the feedback.
Registration is indeed not a domain class. I'm creating the Registration
class myself, because I copied that from the standard controllers generated by Grails:
def create() {
respond new Person(params)
}
I thought the index(Registration r)
only works when you pass a parameter in the URL
No, you are right, this what's happening. However, I had to turn it into a domain class now, because of this: https://github.com/grails3-plugins/fields/issues/7
I'm creating the Registration class myself, because I copied that from the standard controllers generated by Grails.
There shouldn't be any standard controllers generated by Grails that contain code like that which is instantiating anything other than a domain class.
I thought the index(Registration r) only works when you pass a parameter in the URL
That is not correct. That will work regardless of what parameters are in the URL. If there are parameters in the URL (or a body which can parsed that contains a recognized content type) then that information will be used to do data binding.
I'm not saying that Grails code is generating code which doesn't return non-domain classes. I just figured that returning objects like this was a best practice. And in my case it wasn't a domain class, but a command object. That didn't seem like a big difference to me.
And thanks for the update on the parameter handling, I didn't know!
I just figured that returning objects like this was a best practice.
It is. The problem here doesn't have anything to do with returning objects though. The problem is that the construction of your object is failing. You are not even getting to the return.
Is is as if you did this in standard Groovy (no Grails)...
class Widget {
String title
}
def w = new Widget(controller: 'something', action: 'something', age: 2112)
That code will not work for the same reason that your code doesn't work.
In general in Groovy when you pass a Map to a constructor like that, the entries in the Map have to correspond to properties in the instance being created. Domain classes have a special constructor in them which provides different behavior, but since your class isn't a domain class, you have the standard Groovy constructor behavior with respect to this.
I'm trying to return a command object to my view instead of a Domain object, because in this view, I don't use domain objects. So, my code looks like this:
Which gives me the following error: