Using command objects in Grails
Posted By : Akash Sharma | 30-Nov-2013
In this blog I am going to share the details of how to use command object in grails. A command object is a class that is used in conjunction with data binding, usually to allow validation of data that may not fit into an existing domain class.
First of all we have to create a form that submits user details.The name of the form input fields are same as UserCommand class fields name.
userRegistration.gsp
<!DOCTYPE html> <html> <head> <meta name="layout" content="main"/> <g:javascript library="jquery"/> </head> <body> <g:formRemote name="saveUser" url="[controller:'user', action:'register']" update="showErrorInSaveUser"> <label for="name">Username</label><g:textField name="name"/><br/> <label for="emailId">Email Id</label><g:textField name="emailId"/><br/> <label for="password">Password</label><g:textField name="password"/><br/> <label for="password2">Renter Password</label><g:textField name="password2"/><br/> <g:submitButton name="Save User"/> </g:formRemote> <div id="showErrorInSaveUser"> <g:render template="/user/userSaveError"/> </div> </body> </html>
_userSaveError.gsp template
This is template for showing error messages.hasError tag is used just to check before rendering error if an error exists.
<div class='value ${hasErrors(bean:command,field:'name','errors')}'> <div id="nameErrorFromCommand" name="name" >${fieldError(bean:command,field:'name')}</div> </div> <div class='value ${hasErrors(bean:command,field:'emailId','errors')}'> <div id="emailIdErrorFromCommand" name="emailId" >${fieldError(bean:command,field:'emailId')}</div> </div> <div class='value ${hasErrors(bean:command,field:'password','errors')}'> <div id="passwordErrorFromCommand" name="password" >${fieldError(bean:command,field:'password')}</div> </div> <div class='value ${hasErrors(bean:command,field:'password2','errors')}'> <div id="password2ErrorFromCommand" name="password2" >${fieldError(bean:command,field:'password2')}</div> </div>
UserController file
The command object class must be in same file as of controller class.
package com.oodles.practiceblog.auth class UserController { def userRegistration={} def register = { UserCommand command -> log.debug "params for register action :"+params if (command.hasErrors()) { command.errors.allErrors.each{ log.debug "error while saving User domain via RegisterCommand :"+it } render template:"/user/userSaveError",model: [command:command] return } else{ //save user data } } } class UserCommand { String name String emailId String password String password2 def userService static constraints = { name nullable: false, blank: false, minSize: 6 //Apply your own validation condition and validate via database emailId nullable: false, blank: false, email: true, validator: { val, obj -> if( User.findByEmailId(val) ){ return "com.oodles.practiceblog.auth.UserCommand.emailId.validator" } } //validation condition can be executed from a service password nullable: false, blank: false, minSize: 8,validator:{ val, obj -> obj.userService.passwordValidator(val, obj) } password2 nullable: false, blank:false, validator: { val, obj -> if( obj.password != val ){ return "com.oodles.practiceblog.auth.UserCommand.password2.validator" } } } }
UserService service
Custom validation conditions can be checked in service methods.We just need to return proper message type defined in message.properties file in i18n .
package com.oodles.practiceblog import com.oodles.practiceblog.auth.UserCommand class UserService { def passwordValidator(String password,UserCommand command) { if (command.name && command.name.equals(password)) { return 'com.oodles.practiceblog.auth.UserCommand.password.validator' } } }
messages.properties in i18n
Custom error messages can be written in this file.
#custom command object validation errors for UserCommand # {0} for field name # {1} for class name # {2} for value in params # {3} for constraint parameter com.oodles.practiceblog.auth.UserCommand.name.blank=Property {0} must not be blank com.oodles.practiceblog.auth.UserCommand.name.minSize.notmet=Property {0} is less than minimum value of {3} com.oodles.practiceblog.auth.UserCommand.name.nullable=Property {0} must not be blank com.oodles.practiceblog.auth.UserCommand.emailId.blank=Property Email Address must not be blank com.oodles.practiceblog.auth.UserCommand.emailId.email.invalid=Invalid Email Address com.oodles.practiceblog.auth.UserCommand.emailId.nullable=Property Email Address must not be blank com.oodles.practiceblog.auth.UserCommand.emailId.validator=Email Address as {2} already exists com.oodles.practiceblog.auth.UserCommand.password.blank=Property {0} must not be blank com.oodles.practiceblog.auth.UserCommand.password.minSize.notmet=Property {0} is less than minimum value of {3} com.oodles.practiceblog.auth.UserCommand.password.nullable=Property {0} must not be blank com.oodles.practiceblog.auth.UserCommand.password.validator=name must be different from password com.oodles.practiceblog.auth.UserCommand.password2.blank=Property Renter Password must not be blank com.oodles.practiceblog.auth.UserCommand.password2.nullable=Property Renter Password must not be blank com.oodles.practiceblog.auth.UserCommand.password2.validator=Property Renter Password must be same as Password
For more information follow this link and this link.
Thanks
Akash Sharma
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Akash Sharma
Akash is a bright Groovy and Grails developer and have worked on development of various SaaS applications using Grails technologies. Akash loves playing Cricket and Tennis