Migrating from Rails to Grails

I have been developing with Java for over 10 years and over the last couple of years got interested in Ruby and Rails. I have developed a few Rails applications mostly for personal use and use Ruby extensively on the job for utilities that I used write in Perl.

So I am a huge fan of Ruby and Rails, and then along came Grails. Grails is an implementation of Rails written in Groovy. Derived from Java syntax, Groovy is easy for Java developers to pick up. In addition, Grails uses familiar Java frameworks under the covers, most notably Spring and Hibernate. Recently SpringSource acquired G2one, the company behind Grails and some interesting work has been happening to integrate Grails and Spring integration. Reading the Grails documents and various posts, it was clear to me that Grails down-plays its Rails heritage. I expected some significant differences so I thought it would be interesting to port a Rails application to Grails.

I started with the Rails tutorial which guides you through a simple blog application. I used Mysql 5 for the database and got it up and running in no time. The application allows you to post blog entries and comments on the entries. Two tables are created, posts and comments. Of course there is a one-to-many relationship, so a post has many comments and a comment belongs to a post.

I basically wanted to retain the existing database tables and create the application with Grails. In the process, I discovered some of the key differences between these two frameworks.

The first step is to install Grails. It’s best to stick with the stable release. Being adventurous, I decided to check out the latest code from the svn trunk and build it myself. This is currently version 1.0.5. The latest stable version is 1.0.4. There is also a 1.1 beta release. Version 1.0.5, and 1.1 beta are buggy and caused some problems with object relational mapping. I eventually resigned myself to using 1.0.4, and everything worked as expected.

To create the blog application, type
grails create-app blog
This is analogous to the rails command. It creates the directory structure for your application and sets up a default configuration.

Next, configure the data source for Mysql. Edit grails-app/conf/Datasource.groovy, so that it looks something like this (changes are bolded):


dataSource
{
  pooled = true
  driverClassName = "com.mysql.jdbc.Driver"
  username = "root"
  password = "mysql"
  dialect = "org.hibernate.dialect.MySQL5Dialect"
}


hibernate {
  cache.use_second_level_cache=true
  cache.use_query_cache=true
  cache.provider_class=
'com.opensymphony.oscache.hibernate.OSCacheProvider'
}
// environment specific settings
environments {
    development {
      dataSource {
      //dbCreate = "create-drop"
        url = "jdbc:mysql://localhost/blog_development"
      }
    }
    test {
      dataSource {
        //dbCreate = "update"
        url = "jdbc:mysql://localhost/blog_test"
      }
    }
    production {
      dataSource {
      //dbCreate = "update"
      url = "jdbc:mysql://localhost/blog_production"
    }
  }
}

Note that like Rails, Grails provides development, test, and production environments. This configuration provides access to the Mysql database I created with Rails. Note the dbCreate property is commented out. The default behavior for the development environment is to drop and re-create the tables every time you run Grails. In this case, I want to retain the schema and the existing data. Removing this property prevents Grails from destroying the database.

Next, you need to provide the declared driver class. This is the standard JDBC driver for Mysql in this case and is provided in mysql-connector-java-5.0.8-bin.jar, for example. Install this in the application lib directory.

Now, create the domain classes. These are somewhat analogous to the Rails model (ActiveRecord) classes. Grails provides Grails ORM (GORM) which uses Hibernate under the covers. GORM provides some nice features, and a nice DSL, but is somewhat incompatible with Rails in its “convention over configuration.” Key differences include:

  • No pluralization of table names
  • Automatic record versioning for optimistic locking
  • No timestamping records by default. Timestamping uses different field names by default
  • DB column names with underscores are converted to camelCase field names by default

So after some experimentation, the Rails compatible domain classes, providing the same features as in the Rails tutorial , are


class Post {
  String title
  String name
  String content
  Date lastUpdated
  Date dateCreated

  static constraints = {
    title(minSize:5, blank:false)
    name(blank:false)
  }
  static hasMany = [ comments : Comment]

  static mapping = {
    version false
    table 'posts'
    columns {
      content type : 'text'
      lastUpdated column:'updated_at'
      dateCreated column:'created_at'
    }
  }
}


class Comment {
  String commenter
  String body
  Date lastUpdated
  Date dateCreated

  static mapping = {
    version false
    table 'comments'

    columns {
      body type: 'text'
      lastUpdated column:'updated_at'
      dateCreated column:'created_at'
    }
  }

  static belongsTo = [post: Post]
}

Notice the boilerplate code required here. The timestamp fields are Grails defaults and will be automatically updated as appropriate. Unlike, Rails, they must be explicitly declared and mapped to the Rails conventional column names.

Versioning is turned off, as the tables do not include version columns. (I am a big fan of optimistic locking, but this is KISS). The constraints closure in the Post class demonstrates how field validation is done in Grails, similar to the Rails tutorial.

I struggled for a while attempting to refactor this code into a base class. I eventually gave up. GORM provides some conventions around mapping inherited domain classes. Also, I couldn’t figure out how to get the mapping closure to execute the base class mapping. It is likely due to my lack of Groovy and GORM expertise, so I suspect there is an easy way to do this.

From this point, it is fairly straight forward. Execute the commands:
grails generate-all post
grails generate-all comment

to generate the controller and view scaffolding code. Then
grails run-app
and you should be good to go.

As a final step, Grails scaffolding creates inputs for dateCreated and lastUpdated. This also behaves differently then Rails. So I went in and edited the view pages, e.g., grails-app/views/post/create.gsp and removed the date fields.

The blog application on Rails

The blog application on Rails



The blog application on Grails

The blog application on Grails

Advertisements

6 Responses to “Migrating from Rails to Grails”

  1. เกรลส์ หกสิบหก » เทคนิคการ Migrate จาก Rails มาเป็นเกรลส์ Says:

    […] ที่มา https://dturanski.wordpress.com/2009/01/19/rails2grails/ […]

  2. Danelli Holt Voith Says:

    David – I love that picture of Tolly and your Dad. Tolly is really close to the end – hope he will hang in there til I get to Milan in July. D

  3. Michael Kimsal Says:

    Curious as to why you didn’t just let GORM create the column names for you automatically. I’m specifically referring to the mapping of the column names to ‘created_at’ and so on. If you didn’t have those, you’d have columns like “date_created”. Not really a big deal unless you’re dealing with a legacy database.

    Ahh.. “I basically wanted to retain the existing database tables and create the application with Grails.’ Fair enough, if you want to do that, you managed to do it. Most of my projects in Grails are ‘from scratch’ so dealing with legacy schemas isn’t an issue, though I know I have the ability if I need to do so. I suspect most Rails projects are ‘from scratch’ as well, given the conventions (pluralization, etc.) that it adheres to.

    So several months after your post, how are you doing with Grails?

    • David Turanski Says:

      Yes, the experiment was probably a bit contrived, but it did illustrate a few subtle differences between the two stacks. The name “Grails” connotes some degree of “Rails” heritage, but apart from a similar development style, the two diverge pretty quickly. I haven’t had a chance to do much with Grails since this.

  4. Michael Kimsal Says:

    Yeah, the naming is a bit unfortunate, imo. Beyond “convention over configuration” the philosophies differ a bit. The primary difference I see is that the Rails stack is almost all written ‘from scratch’ (with all the pros and cons that entails) and the Grails stack is many pre-done pieces (spring/hibernate/sitemesh/etc) prewired together, again, with all the pros and cons that brings with it.

    Welcome to the Grails community, if only on a part-time casual basis. 🙂

  5. Uroš J. Drifter Says:

    I’m loving grails 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s