Fork me on GitHub

25 Feb 2010

Using a custom data binder with Grails domain objects

Yesterday I read a post by Stefan Armbruster on how to register a custom data binder to lookup Grails domain objects by any arbitrary property. I wanted to go a little further so that I could not only bind existing domain instances but create new ones as well.

For example, let's say I have Artist and Album domain classes where Artist hasMany Albums and Album belongsTo Artist. Artist has a name property that is unique. On my create album page I want to be able to type in the artist name and have the save action in the controller automatically lookup an existing Artist instance or create a new one if it doesn't exist. Doing this I don't want to have to add or change anything in the save action itself - I could theoretically use dynamic scaffolding.

Adapting Stefan's PropertyEditor implementation I created this:
The crucial change is the if (!value) block which creates the new instance and populates the relevant property.

To make everything work I just need to:
  1. Add the PropertyEditorRegistrar and place it in resources.groovy as per Stefan's post.
  2. Have a text input or autocompleter with the name "artist" in my create album form.
  3. Add artist cascade: "save-update" to the mapping block in Album so that when the Album is saved the new Album will get saved as well.

7 comments:

Anonymous said...

Returning a new instance in case that an object is not found is definitely a good point.

Unknown said...
This comment has been removed by the author.
Unknown said...

thank you very much, this is exactly what I needed for my Country table ^^

Anonymous said...

Using the ?: operator, there a more groovy way to implement setAsText as a one-liner:

void setAsText(String text) {
domainClass."findBy${StringUtils.capitalize(property)}"(text) ?: domainClass.newInstance((property): text)

}

Jérémy MARC said...

I am trying to use the same code but I have an StackOverflowError in the line :
propertyEditorRegistry.registerCustomEditor(Account, new DomainClassLookupPropertyEditor(domainClass: Account, property: "name"))

Dont know why

michaelvk said...
This comment has been removed by the author.
Puremelda said...

All our writers understand writing services online standards, and they are always ready to work for you. Students can online essay writing services in any field and on any level of education.