Reputation: 504
On looking for a solution for a two-domain-classes-in-one-view problem, I ran into the scaffolding tutorial for grails where I saw this:
class BookController {
def scaffold = Book
// overrides scaffolded action to return both authors and books
def list = {
[ "books" : Book.list(), "authors": Author.list() ]
}
}
And it says underneath:
All of this is what is known as "dynamic scaffolding" where the CRUD interface is generated dynamically at runtime.
I'm quite new to the scaffolding concept, and there is something I don't get here. I expect that the list.gsp is dynamically generated based on the controller return parameters, thus enabling me to have both lists in one view. I don't know if this is possible, it's just the thing that I expect to magically happen here. So please, correct me if I'm wrong.
If this should be the case, then something goes wrong in my application and I get:
org.codehaus.groovy.grails.web.pages.exceptions.GroovyPagesException: Error processing GroovyPageView: Tag [paginate] is missing required attribute [total] at /customer/list:45
So this is something in the view, which I don't have, because I'm expecting it to get scaffolded. Could it be that the error is caused by the fact, that I use the default templates? Should I create a new template specially for my needs? Also, is there some aricle on grails lifecycle, so that I can see what gets passed when?
Thank you all for the help, al
Upvotes: 0
Views: 1771
Reputation: 5029
Interestingly, in overriding the index() action so that I could sort the result differently, I found that in Grails 2.3.7, the default values are now bookInstanceList
and bookInstanceCount
.
The documentation hasn't changed from bookInstanceTotal
!
These names are further decided by the following setting in grails-app/conf/Config.groovy
:
grails.scaffolding.templates.domainSuffix = 'Instance'
Upvotes: 0
Reputation: 13495
If you're scaffolding Book class, it will only scaffold list of Book
s.
You can issue a command grails install-templates
to see what scaffolding does. You can safely delete the src/template/scaffolding afterwards.
In your case, list.gsp template is expecting two variables: bookInstanceList
and bookInstanceTotal
. bookInstanceTotal
is a value of required total
parameter to [paginate][2]
tag, so you get the mentioned error.
Upvotes: 1
Reputation: 3560
I believe you have misunderstood that section of the Grails documentation. By default, scaffolding provides an index, list, show, edit, save, update, and delete action. However, when they Grails documentation says that you can return both Books and Authors, it doesn't mean that it will automatically scaffold a new view for BOTH books and authors. It is saying that if you want to go and create a new 'list' view, i.e. grails-app/views/book/list.gsp
you can make it so that the application will use your list
closure and view instead of a scaffolded one.
Now, you've run into a bit of Grails trivia that I have never considered before. What if you override a scaffolded closure without specifying a new view, will Grails give a 404 or will it use the scaffolded view? It appears that it uses the scaffolded view. As such, the default list view uses pagination, and it expects to see an xxxInstanceListTotal
variable which the paginate tag then uses for its total
attribute. Since there's no value provided, paginate throws the exception seen there.
Scaffolding is pretty basic functionality, it's not smart enough to show a combined list of Books and Authors.
Upvotes: 2