Showing posts with label grails. Show all posts
Showing posts with label grails. Show all posts

Thursday, February 4, 2010

Use Exceptions To Control Validation Flow.

When using default grails scaffolding a controller action, for example save, will look some thing like this


def save = {
        def fooInstance = new Foo(params)
        if(!fooInstance.hasErrors() && fooInstance.save()) {
            flash.message = "Foo ${fooInstance.id} created"
            redirect(action:show,id:fooInstance.id)
        }
        else {
            render(view:'create',model:[fooInstance:fooInstance])
        }
    }

This has a number of problems.

First it is difficult to move this code into a service, because you cannot call render from a service.  Not moving this code to a service decreases reuse, and means that the database code is not transactional.

There are many reasons why you should use exceptions instead of return code logic to handle this tpe of error, some of them are detailed here.  The nested if else statements are hard to read, and it is easy for code to continue executing as if nothing had happened.

Runtime Exceptions in a service cause the transaction to be rolled back, which is the desired behavior when a validation error has occurred.

So what we want to do is move the code that saves foo to a service, and throw an exception if the input is not valid.  We will then catch the exception in the controller and render the create view.


Listing 2 FooService
class FooService {
  boolean transactional = true

  Foo saveFoo(Map params) {
    def fooInstance = new Foo(params)
    if (!fooInstance.hasErrors() && fooInstance.save()) {
      return fooInstance
    } else {
      throw new ValidationException("Foo is not Valid", fooInstance)
    }
  }
}

Tip: If you are using grails 1.2 support for this is built into the framework  You can now call save(failOnError:true)  and and exception will be thrown.  Or better yet you can set the configuration parameter grails.gorm.save.failOnError = true to enable in your entire application


Listing 3 FooController
class FooController {
  def fooService

  def save = {
    try {
      def fooInstance = fooService.saveFoo(params)
      redirect(action: show, id: fooInstance.id)
    } catch (ValidationException e) {
      log.warn("Validation Failed on Foo ${e.message}" )
      render(view: 'create', model: [fooInstance: e.invalidObject])
    }
  }
}


Listing 4 Validation Exception
class ValidationException extends RuntimeException {
  Object invalidObject
  
  ValidationException(String message, Object invalidObject){
    super(message)
    this.invalidObject = invalidObject
  }
}


If you fly and have an iphone you should check out this awesome holder for watching videos in flight. I use mine all the time!! 

Monday, December 21, 2009

Grails Plugins With In-House Repository Part 1 (Introduction).

In this series of posts I am going to cover how to use grails to create and use a plugins to develop your application.  

Grails plugin system is one of the most powerful features of the framework. If you have been using grails for any length of time you have probably started using some of the rich plugins available in the grails plugin repository.   Grails plugins go much further than just adding third party libraries. They  allow for true modular application development, by letting you create a plugin for each feature area in your application.  Each of these plugins can contain views, controllers, library dependencies, and domain classes. They can interact with the spring application context, participate in generating the web-xml, and even add dynamic methods to grails artifacts.  As with most things in grails it is easy to create and use plugins, and the payoff is tremendous.  Every time you add new features to your application you should be thinking, "can I make this a plugin?"

If you are not already familiar with developing plugins you should start by reading this tutorial by Scott Davis, and reading the section on Plugins in the Grails Framework Documentation.

You now have a choice of sharing your plugin with the world by publishing it to grails central repository, or publishing to a private in-house repository. If you want to publish to central repository see this article.

In many cases it makes sense to set up a private repository to manage your plugins.   You may wish to over-ride some of the plugins hosted in the central repository, or you may be developing proprietary / closed source plugins for use in your organization.  Grails allows you to manage your plugins using a subversion repository.  This repository is used to manage both the source for your plugin, and the distributable .zip file.  (Note in grails 1.2 it will be possible to manage the source in a different repository).  The grails release-plugin command will take care of creating the correct directory structure in your repository, committing source files, and tagging each release.


You will want to get started by creating a new subversion repository to host your plugins.  You will also need to set up your subversion repository for access via http.(Grails assumes http/https as the protocol you can't use svn:// urls).  You probably also want to consider restricting access to your plugin repository by setting up authentication.

That is all for today's post.  In the next post I will cover how to set up your plugin to publish to this repository, and how to use plugins from this repository in your applications.  

Friday, January 9, 2009

Releasing a New Version of an Existing Plugin

In this post I am going to cover releasing a second version of your plugin.  It is inevitable that you will need to make changes to your plugin after its first release.  I would recommend also reading part one, and part two of this series. Here are the steps you will need to follow to successfully update your plugin.

Step one: You need to obtain a working copy of your source from the plugin repository.  If you attempt to release a second version of your plugin with out performing this step you will get errors.
To check out your source run the following command.
svn co http://myrepository.mydomain.com/svn/repsitory/grails-/trunk my-plugin
Tip: if you are using grails 1.2  and you wish to manage your sources somewhere other than subversion you can add --ziponly flag to the grails release plugin command (grails release-plugin -repository=myRepository --zipOnly).  You are then free to manage your plugin source in what ever source control suits your needs.

Step two: Add any source files that are ignored by grails package-plugin.   When grails automatically released your plugin it ignored certain artifacts.  Some of these are useful when you are testing your plugin via grails run-app, this includes : Config.groovy, UrlMappings.groovy, and any files in your plugins exclude list.  It also did not check in your grails-app/conf/BuildConfig.groovy file which is essential to re-releasing your plugin.  You will need to create the conf directory mkdir grails-app/conf.  You will then need to re-create or copy the BuildConfig.groovy file as explained in part 2.

Tip: For testing purposes a  grails plugin can be run with run-app just like any other grails application.  That is why it is often useful to have files checked into your source tree that are not packaged as part of the plugin. 



Step 3: You will now need to make the required changes to your plugin.  Don't forget to update the plugin version in application.properties and more importantly in GrailsPlugin.groovy. You will need to do a subversion add for any new files you add to your plugin. 


Tip a great way to test your plugin and to speed up time in developing it is to use it as part of a real application.  In grails 1.1 and later this is easy.  You simply add the following to your BuildConfig.groovy file.
grails.plugin.location.="/full/path/to/directory/you/checkedout/in/step/one"
See Grails 1.1 release notes for more info
If you are lucky enough to be using Intelij 9 it will automatically add a new grails module for this plugin.


Step 4: Release your new plugin to the repository.  This step is the same as the first release you simply run
grails release-plugin -repository=
Grails will perform the following steps. 
  • check in all of your updates to the trunk,
  • tag the new version of your plugin
  • update the LATEST_RELEASE tag 
  • update and checkin a new .plugin-meta/plugins-list.xml file.  
That's it!! now you can advertise your new functionality to your co-workers.  They will be amazed and awed at your talent, and how much time you saved them by sharing your work as a plugin :)


Check out this upcoming book on developing grails plugins.