I’m pretty excited about Rails 3.0. It really feels like a polished version of the framework, much like Snow Leopard was for Leopard OS X.
At this stage in the game I really don’t want to be starting any new projects with Rails 2.3.5, so I thought I would see if it was possible to get Rails 3.0-beta running with “My Stack”—a set of gems/plugins used on all of my projects. Admittedly, there are probably some others that I should be using, but these are definitely the essentials:
- haml (with sass)
- compass
- authlogic
- shoulda
- factory_girl
- will_paginate
Just to keep things interesting I thought I would throw Ruby 1.9.1 in there to mix things up.
First, stop was to check out railsplugins.org. A registry setup by Engine Yard to track which plugins are Rail 3, Thread Safe, JRuby, and Ruby 1.9 compatible. Let’s see how my stack faired (note, I’m only interested in Rails 3 and Ruby 1.9):
OK, let’s look at each plugin, step by step:
Haml (Confirmed to work)
Installing Haml was pretty straight forward:
# Gemfile
gem "haml", "2.2.21"
# command line (rails root of course)
bundle install
haml --rails .
Compass (Confirmed to work)
Install Compass was also straight forward:
# Gemfile
gem "compass", "0.10.0.pre9"
# command line
compass --rails -f blueprint . --css-dir=public/stylesheets/compiled --sass-dir=app/stylesheets
Authlogic (Unknown to work)
While Authologic is officially “not working”, reports from end users suggest it is. Following along with Ryan Bates screencast, you just need to translate the script/generate commands to rails generate and also check for new options. To setup Authlogic with your application, add it to your Gemfile.
# Gemfile
gem "authlogic", :git => "git://github.com/binarylogic/authlogic.git"
Shoulda (Unknown to work)
There are no reports regarding shoulda (as there is no version number assigned to, and you can't comment without a version number). Although there is a rails3 branch, it hasn’t been touched since mid-January. Well let’s give it a go and see how far we get:
# Gemfile
gem "shoulda", :git => "git://github.com/thoughtbot/shoulda.git", :branch => "rails3", :group => :test
A couple of options to note. :branch specifies the branch of the git repo, and :group the environment. You won’t be needing shoulda in production.
So how did we get on? Trying rake test... Boom!
DEPRECATION WARNING: RAILS_ROOT is deprecated! Use Rails.root instead. (called from join at ~/.bundle/ruby/1.9.1/bundler/gems/shoulda-b78dbf514bbce3272023d3a4742474857c2eb3c3-rails3/lib/shoulda/autoload_macros.rb:40)
~/.bundle/ruby/1.9.1/bundler/gems/shoulda-b78dbf514bbce3272023d3a4742474857c2eb3c3-rails3/lib/shoulda/autoload_macros.rb:40:in `join': can't convert #<Class:0x1297f3c> into String (TypeError)
OK, let’s remove shoulda gem from:
rm -rf ~/.bundle/ruby/1.9.1/bundler/gems/
And let’s try a more up to date fork. This looks like it:
# Gemfile
gem "shoulda", :git => "git://github.com/bmaddy/shoulda.git", :branch => "rails3", :group => :test
You get this message but it doesn’t appear to be anything to worry about (I hope):
shoulda at ~/.bundle/ruby/1.9.1/bundler/gems/shoulda-87e75311f83548760114cd4188afa4f83fecdc22-rails3 did not have a valid gemspec.
This prevents bundler from installing bins or native extensions, but that may not affect its functionality.
The validation message from Rubygems was:
["test/rails_root/db/development.sqlite3", "test/rails_root/doc", "test/rails_root/log/development.log", "test/rails_root/log/production.log", "test/rails_root/log/server.log", "test/rails_root/log/test.log", "test/rails_root/test/fixtures", "test/rails_root/test/functional", "test/rails_root/test/integration", "test/rails_root/test/unit"] are not files
And running rake test works. Let’s convert a controller over.
context "create card" do
setup { post :create, :card => cards(:one).attributes }
should_change "Card.count", :by => 1
should_redirect_to("new card") { card_path(assigns(:card)) }
end
Almost works, but dies on the should_change marco.
1) Error:
test: create card should change Card.count by 1. (CardsControllerTest):
NoMethodError: undefined method `call' for #<Arel::Value:0x172eba8>
~/.bundle/ruby/1.9.1/bundler/gems/shoulda-87e75311f83548760114cd4188afa4f83fecdc22-rails3/lib/shoulda/macros.rb:45:in `block in should_change'
~/.bundle/ruby/1.9.1/bundler/gems/shoulda-87e75311f83548760114cd4188afa4f83fecdc22-rails3/lib/shoulda/context.rb:360:in `call'
~/.bundle/ruby/1.9.1/bundler/gems/shoulda-87e75311f83548760114cd4188afa4f83fecdc22-rails3/lib/shoulda/context.rb:360:in `block in create_test_from_should_hash'
Looks like a change in ActiveRecord is causing a few problem there.
Conlusion on Shoulda: OK, it might be the only macro failing, but I think at this stage i will leave shoulda at this point. I’ve filed an issue and if I have some time I will look into it myself.
Factory Girl (Unknown to work)
While the owner says it’s “not working”. A commentator says it does. Let’s give it a go:
# Gemfile
gem 'factory_girl', :git => 'git://github.com/szimek/factory_girl.git', :branch => 'rails3', :group => :test
# command line
bundle install
And convert a controller over to use factories instead of fixtures (yuk!).
# factories.rb
Factory.define :card do |c|
c.name 'Lorem ipsum dolor sit amet'
end
# cards_controller_test.rb
require 'test_helper'
class CardsControllerTest < ActionController::TestCase
setup do
@card = Factory(:card)
end
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:cards)
end
test "should get new" do
get :new
assert_response :success
end
test "should create card" do
assert_difference('Card.count') do
post :create, :card => @card.attributes
end
assert_redirected_to card_path(assigns(:card))
end
test "should show card" do
get :show, :id => @card.to_param
assert_response :success
end
test "should get edit" do
get :edit, :id => @card.to_param
assert_response :success
end
test "should update card" do
put :update, :id => @card.to_param, :card => @card.attributes
assert_redirected_to card_path(assigns(:card))
end
test "should destroy card" do
assert_difference('Card.count', -1) do
delete :destroy, :id => @card.to_param
end
assert_redirected_to cards_path
end
end
Yes, it’s a very simple example of using a factory. So there might be some bugs lurking around. But I’m guess it’s safe to say this is usable.
Will Paginate (Confirmed to work)
This looks promising.
# Gemfile
gem "will_paginate", "3.0.pre"
# command line
bundle install
Again, it’s a simple example, but I think it’s safe to say we’re good to go.
# cards_controller.rb
@cards = Card.paginate :page => params[:page], :per_page => 1
# index.html.haml
= will_paginate @cards
Conclusion
Well it is marked Beta for a reason—and that’s for the gem/plugin ecosystem to catch up. With my limited playing with Rails 3-beta I would be confident writing applications with it, and while most plugins seem to be compatible, I feel a little uneasy doing production projects until there is a broader range of plugins compatible with it. Looks like I will be staying with Rails 2.3.5 a little longer.