What? You’re still generating migrations manually? I don’t anymore. I have tools which do it for me.

Hobofields is a set of extensions to ActiveRecord that gives us lots of goodies, including the ability to generate migrations automatically. The key to achieving this automatic property declaration is schema declaration in the model.


1 class Post < ActiveRecord::Base
2 fields do
3 title :string
4 published_at :datetime
5 timestamps
6 end
7 end

If you ever used DataMapper, the idea is similar. Where Hobofields shines though is in reading your model and inferring many, many conventions:


1 class Comment < ActiveRecord::Base
2 belongs_to :post
3 end

Running the hobo_migration generator results in:


1 $ script/generate hobo_migration
2
3 -———- Up Migration -———-
4 add_column :comments, :post_id, :integer
5
6 add_index :comments, [:post_id]
7 -———————————————-
8
9 -———- Down Migration -——-
10 remove_column :comments, :post_id
11
12 remove_index :comments, :name => :index_comments_on_post_id rescue ActiveRecord::StatementInvalid
13 -———————————————-

If you use acts_as_list, Hobofields also knows to add a position column (or whatever name is needed):


1 class Comment < ActiveRecord::Base
2 acts_as_list
3 end

Running the migration generator, you get:


1 $ script/generate hobo_migration
2
3 -———- Up Migration -———-
4 add_column :comments, :position, :integer
5 -———————————————-
6
7 -———- Down Migration -——-
8 remove_column :comments, :position
9 -———————————————-
10 What now: [g]enerate migration, generate and [m]igrate now or ©ancel?

Another thing I love about Hobofields is rich type support. Need Textile?


1 class Post < ActiveRecord::Base
2 fields do
3 body :textile
4 end
5 end


1 content = <<EOTEXTILE
2 This is some Textile content
3
4 h1. Automatically formatted
5
6 To your:
7
8 * specifications,
9 * using standard tools

10 EOTEXTILE

11
12 Post.new(:body => content).body.to_html
13 #=> "<p>This is some Textile content</p>\n<h1>Automatically formatted</h1>\n<p>To your:</p>\n<ul><li>specifications,</li>\n<li>using standard tools</li>\n</ul>\n"

Or maybe you need an enumeration?


1 class Comment < ActiveRecord::Base
2 fields do
3 status enum_string(:spam, :ham), :default => :spam, :required => true
4 end
5 end


1 $ script/generate hobo_migration
2
3 -———- Up Migration -———-
4 add_column :comments, :status, :string, :default => "ham", :required => true
5 -———————————————-
6
7 -———- Down Migration -——-
8 remove_column :comments, :status
9 -———————————————-


1 >>Comment.new.status
2 #=> "ham"
3 >> Comment.create!(:status => "foo")
4 #=> ActiveRecord::RecordInvalid: Validation failed: Status must be one of spam, ham

Admittedly, this last example could be better handled with Hobo’s lifecycle (state machine) implementation, but still, it’s nice that the validation already exists. Using :null =&gt; false, :required =&gt; true creates the appropriate validation as well:


1 class Comment < ActiveRecord::Base
2 fields do
3 author :string, :required
4 email :string, :required
5 status enum_string(:spam, :ham), :required => true, :default => "ham"
6 timestamps
7 end
8 end

And Hobofields is smart enough to know when no changes are required:


1 $ script/generate hobo_migration
2 Database and models match — nothing to change

But with this model definition, we now have new validation automatically:


1 >> Comment.create!
2 #=> ActiveRecord::RecordInvalid: Validation failed: Author can’t be blank, Email can’t be blank

Oh wait, just realized that the email address should be an email address:


1 class Comment < ActiveRecord::Base
2 fields do
3 email :email_address, :required
4 end
5 end


1 >> Comment.create!(:email => "a")
2 #=> ActiveRecord::RecordInvalid: Validation failed: Author can’t be blank, Email is invalid

I really enjoy Hobofields for all the goodies it brings to the table. I haven’t even started on all the automatic scopes goodies, the lifecycle methods (which I haven’t used yet), or scoped associations.

Until we meet again tomorrow, I suggest you read Hobofields Reference, as well as Hobofields rich types to get the full goods.

Recently, a friend asked me to help him rewrite the Access database they use to track donations into something better. I offered to rewrite as a web app (surprise!), and chose to use Hobo.

I’m not a designer, and it shows. My apps are horrible, and have bad choice of color. Red on blue? Check. Green on orange? Check. Wide margins and misaligned text base? Check. Name any design mistakes, and I can make it happen.

I had seen Hobo used by another developer, and I was impressed with the ActiveRecord extensions. There was also the fact that Hobo has a pleasing design that could serve as an initial draft, until external help can be acquired.

Hobo isn’t really different from Rails: hobo name_of_new_app. Done.

Things I liked immediately: Declarative declaration of fields and validations, automatic generation of migrations, permissions built-in. You know, stuff that covers the 80%

The thing I didn’t like: DRYML. Don’t get me wrong: DRYML is a very nice tool, and I didn’t have any problems understanding the implicit context. All I had was the age-old problem: learning a new API. After 2-3 weeks (very part time), I was more comfortable with the different tags, and how to use them.

I really enjoy writing this:


1 <table-plus fields="this, city.name, toll_free_number, main_number"/>

and receiving this in return:




Click for larger view

Right now, I’ve had a very positive experience with Hobo. Having good documentation helps a lot, and Hobo hasn’t disappointed: http://cookbook.hobocentral.net/

Over the next few days, I’ll discuss Hobo in more details. Hope you follow along!

Search

Your Host

A picture of me

I am François Beausoleil, a Ruby on Rails and Scala developer. During the day, I work on Seevibes, a platform to measure social interactions related to TV shows. At night, I am interested many things. Read my biography.

Top Tags

Books I read and recommend

Links

Projects I work on

Projects I worked on