I want a link to open up another view in my webapp to display information about the specified object. What is the best way to pass objects between controllers actions in grail?
3 Answers
Actions can be chained using the chain controller method.
Chaining allows the model to be retained from one action to the next.

- 12,772
- 11
- 42
- 73
The earlier answers are incomplete. So, I am compiling them along with my inputs and making them clearer.
You have two options:
Chaining the actions:
def action1() = { DomainClass domainInstance = DomainClass.findById(params.id); chain (action: 'action2', model: [domainInstance: domainInstance]); } def action2() = { DomainClass domainInstance = chainModel?.domainInstance ?: DomainClass.findById(params.id); [domainInstance: domainInstance]; }
However, the successor action seems to use a fresh database session instead of reusing that of the predecessor (which may also be configurable in Grails, I don't know how though). So any lazily loaded entity may not be fully loaded in the successor action and may give LazyInitializationException (depending on your ORM configuration of course).
Forwarding the request:
def action1() = { DomainClass domainInstance = DomainClass.findById(params.id); forward (action: 'action2', model: [domainInstance: domainInstance]); } def action2() = { DomainClass domainInstance = request?.domainInstance ?: DomainClass.findById(params.id); [domainInstance: domainInstance]; }
Unlike in the previous case, request forwarding reuses the existing session so lazy loading issues will not occur.
As you can see, the syntax for both is almost identical. But one should prefer request forwarding as per the requirement in question due to the issue mentioned above. Another important detail is regarding the URL viewed in the address bar on/after page loading. Forwarding the requests will PRESERVE the page URL while chaining the actions will CHANGE the page URL to that of the latest action.

- 325
- 3
- 12
(Late to the party, but...) I'm using Grails 2.4.4, which allows me to do the below:
def usernameLogin() {
SecurityToken securityToken = authService.loginWithUserPass(params.user, params.pass)
chain action: 'afterLogin', model: [securityToken: securityToken]
}
def ssoLogin() {
SecurityToken securityToken = authService.ssoLogin(params.remoteUser, params.key)
chain action: 'afterLogin', model: [securityToken: securityToken]
}
def afterLogin() {
SecurityToken securityToken = (SecurityToken) chainModel['securityToken']
if (securityToken.valid) {
forward action: 'loggedInRedirect'
}
else {
forward action: 'loginFailed'
}
}
- SecurityToken is an object that contains string and enum
- The key is 1) using "chain action" in source action, 2) using chainModel in target action
Hope this helps.

- 1,064
- 9
- 23