Grails First Impressions – GORM vs. ActiveRecord
This blog entry is about my thoughts and observations while I'm starting to learn Grails. At the onset, the primary thing I've concerned myself with is the domain layer (what Ruby on Rails calls “models”). For the purposes of my impressions, I'm going to compare Grails' GORM with Ruby on Rails' ActiveRecord.
To begin with, both frameworks have an environment-aware database configuration file. However, the way in which these configurations are represented differ – ActiveRecord uses a YAML file filtered through ERB to support runtime data. GORM uses a native Groovy file. Of the two approaches, I'm going to have to side with GORM on this. The whole concept of RoR was to keep configurations within code, and yet right from the onset they violate their own rule. GORM adheres to this, and very elegantly. The GORM configuration file looks a lot more structured than ActiveRecord's YAML file, and offers an impressive selection of options, allowing you to configure such things as caching. More power and choice to the developer.
From that point on, the 2 framework diverge significantly.
ActiveRecord is based on using database migration scripts to construct tables. Once the tables are created, ActiveRecord dynamically creates the model's getters and setters based on the column names within the table. Constraints and validations are done via “validates_XXX” class methods, and allowing you to define your own custom “validate” and “validate_on_XXX” methods.
GORM's mechanism is to define all your data directly in the domain class. Upon deployment/execution of your webapp, GORM queries the table, and dynamically alters the table as needed to cater for the domain. All the constraints and validations are defined directly within the domain class, which are used both for constructing the table as well as data validation.
As you can immediately see, GORM's mechanism requires significantly less typing than ActiveRecord's.
An interesting feature of GORM is the ability to declare the table structure “manually”, meaning you can say “this property maps to this column name of this type”. What's the point of this? It means that GORM can be used with pre-existing tables right out the box. ActiveRecord is notorious for not playing well with existing infrastructures. This support extends further to support different types of ID's. ActiveRecord only works with auto-generated ID numbers - GORM allows you a lot more control over what the primary key of the table is, right down to different data types other than integers.
The one feature of GORM that made me giddy was referential integrity. GORM supports foreign keys, and integrity right out the box – complete with support for “on delete” and “on update” with “cascade” or “restrict”. See my other blog post on “Data is Sacrosanct”.
Another truly powerful feature of GORM is the use of domain events (such as inserting, updating, etc.) ActiveRecord offers a certain degree of events on a model, but some obvious ones are missing, most notably “onLoad”.
Continuing it's tradition of offering choices, GORM supports a similar infrastructure for doing what ActiveRecord calls “Single Table Inheritance” (in GORM this is called Mapping Inheritance). As with everything else so far, GORM's implementation is hugely more simplified than ActiveRecord's. With ActiveRecord, a developer must include a specially named text column in the table structure, and include all possible columns required for the various subclass types.
By contrast, GORM automatically knows that a domain must support subclassing (talk about magic!), automatically creates the required column for differentiating between subclasses (if needed), and automatically includes all the columns defined in the subclasses. But you have another choice. GORM offers the capacity for each subclass to have it's own unique table containing only the additional columns required for the subclass – the superclass has it's own table created. Querying across the tables is completely automatic. This is a lot more in line with good database normalisation (something the developers of ActiveRecord completely ignored).
There's “magic” but it's logical magic.
When it comes to querying the database, both frameworks offer a “find_by_XXX” or “findByXXX” mechanism where the criteria can be automatically detected by the method name itself. This is fine for simple queries, but when it comes to complex queries, again the offerings from the frameworks difference.
ActiveRecord gives you the “:conditions => 'x = 1'” option. GORM offers a much more powerful alternative: you can construct a “criteria” object, and programmatically define the criteria. This is a lot more OO than ActiveRecord, and also separates your query for the underlying inner workings of the database engine. Switching between database engines becomes a snap.
I've got a lot more experimenting to go, but so far, I have to admit that I am loving Grails. It offers all the strengths that I appreciated under Ruby on Rails, but suffers from none of the shortcomings.
Comments
Thank you for the great post. I've used Ruby on Rails and Grails. The reasons you gave us and some more I prefer Grails.
I don't like "magic" or magic should be absolutely logical. Ruby on Rails has too much magic for me.
Greetz, Konstantin
Thank you for the great post. I've used Ruby on Rails and Grails. The reasons you gave us and some more I prefer Grails.
I don't like "magic" or magic should be absolutely logical. Ruby on Rails has too much magic for me.
Greetz, Konstantin
Very nice article. I've felt exaclty the sane when I was reading a RoR book.
Besides that, just to give credit to the right tool, most of the benefits of GORM are inherited from Hibernate.
Cheers
Add comment
Visit my Friends and Family
If you've enjoyed my site, please take a moment to visit my friends and family, many of whom have some interesting insights, and entertaining thoughts and ideas.
- Crause Family - the family website
- Peter Crause - my father
- Justin Crause - my brother
- Cencina Photomagic - great photographer