Predefined records in migration?

What would be a good way to create some predefined instances in the
database for a certain model? For example: categories, genres or user-
roles? They are pretty fixed, although you might want to add or remove
some at a later stage.

Is it a good idea to put something like this in the migration itself?

def self.up
  create_table :roles do |t|
    ..
  end

  Role.create :name => 'admin'
  Role.create :name => 'moderator'
end

Hi, yep thats fine if you think they are quite static and not likely
to change. Or you could add them as fixtures and use "rake
db:fixtures:load" to load them into your database.

Both of those are bad ideas in my opinion.

Fixtures should be used for test data only. Migrations seem like a logical spot for defalt data, but they can become brittle if you try to place records into the database at that time, as future changes to code (validations, before_ callbacks, etc) can make them fail, killing your remaining migrations. Even if it seems like you can get away with it, I wouldn’t.

Here’s the way I do it… by making my own rake task.

In your lib/tasks folder, create a file called import.rake

Place this code in the file

namespace :db do
desc “import initial database contents”
task :import => :environment do
admin = User.create(:login => “admin”, :password =>“1234”, :password_confirmation=>“1234”, :email=>“admin@domain.com”)

  admin_role = Role.create :name => 'admin'
  moderator_role = Role.create :name => 'moderator'
  admin.roles << admin_role
  admin.roles << moderator_role

end
end

Save it, then run

rake db:import

or

rake RAILS_ENV=“production” db:import

And you’re all set. Make that part of your deploy:cold step in capistrano :slight_smile:

Good luck!