Archive for the ‘rails’ Category
Using Models In Rails Migrations
It is quite tempting to use models in rails migrations.
At the time the migration is expected to run, the model class will have been updated already, so it is hard use that in the migration itself, even though it would be useful.
Consider this example:
class CreateUsers < ActiveRecord::Migration def self.up t.string :email, :null => false t.string :password, :null => false end # create a dummy user - with newer rails versions this should really go in seeds.rb! User.create!(:email => 'user@example.com', :password => 'demo') end def self.down drop_table :users end end
Doesn’t get simpler than this!
Now lets add another migration:
class AddSSNForUser < ActiveRecord::Migration def self.up add_column, :users, :ssn, :string, :null => false end def self.down remove_column, :users, :ssn end end
And a corresponding validation to the User model:
class User < ActiveRecord::Base # ... validates_presence_of :ssn # ... end
Now if you were to run the database migrations on an empty database, the first migration would fail because of the lack of a SSN. Worse, it is quite possible that the User class is now called something else.
How do you get around this issue:
class CreateUsers < ActiveRecord::Migration # define your own User class class User < ActiveRecord::Base #... end def self.up # clear all cache that rails maintains about the User class/table mapping User.reset_column_information create_table :users do |t| # whatever we did in the example above end # this statement will always work no matter what. User.create!(:email => 'user@example.com', :password => 'demo') end def self.down drop_table :users end end
Sometimes using SQL for performing data migrations could get quite cumbersome and unreadable, and using model objects is the simplest way to run any form of data migration. In such a case, it’s better to copy your model code into the migration.
Controller Testing in Active Scaffold
I just started my adventure with rails a few nights ago. Figured that Active Scaffold based controllers do something that is different from the default controllers generated by the scaffold generator.
For one all controller tests broke when I moved to active scaffold. Here’s a blog post that talks about testing active scaffold based controllers.