Tuesday, March 9, 2010

Loading seed data with Seed-Fu plugin



Loding seed (default) data for lookup database tables is common to the most applications.Rails provide different mechanisms to accomplish this task. I have found the implementation with a plugin called seed-fu very simple and easy to implement.

Seed-Fu is based around loading ruby scripts located in db/fixtures via a Rake task.We just place the ruby files with the code to load seed data into the db/fixtures folder followed by executing the "db:seed" rake command .The plug in handles the rest.

Looking into the details of one of the seed data file will present a clearer view.We have a model named "Role" and want to populate seed data for this.We place a file named "roles.rb" into the "db\fixture" folder.The file name can be anything but "roles.rb" but we stick to the convention here.The file content as follows:


# # db/fixtures/roles.rb
# # put as many seeds as you like in

Role.seed(:name) do |s|
 s.name ='Admin'
 s.description = 'Administrator of the system'
end

Role.seed(:name) do |s|

 s.name ='Developer'
 s.description = 'Developer of a project'
end

Role.seed(:name) do |s|
 s.name ='Product Owner'
 s.description = 'Product owner of a product'
end


We want to add 3 roles (Admin,Developer and Product owner) so we put 3 "Role.seed" block and populate the "name" and "description" attributes.When we run "db:seed", the roles database table will be populated accordingly.

What will happen if we add some more seed data files later and run "db:seed" rake command? Will the role data will be duplicated? It would normally but we have taken a guard :)

Look at the parameter ":name" after the "Role.seed" method call in the above file.The "Role.seed" method takes a comma separated list of symbols that represent some of the key attribute names of the corresponding model ("Role" here).Before inserting a new row, seed-fu checks whether a row with the key values already exists.If a row exists, no data is inserted.

In the above example we have provided ":name" as the key column/attribute name.Before inserting the first "Role.seed" block,seed-fu conducts a search in the "roles" table for a row with the value "Admin" in "name" field.If a row exist, it skips the block(duplicate row not added) and try to proceed with the same rule for the next blocks.

Once you have set up your fixtures, it’s simple to run them:

rake db:seed

or

rake db:seed RAILS_ENV=<development| test | production>


Make sure to populate the database schema with "db:migrate" or "db:schema:load" before you run the "db:seed" command.

You can download the latest version of seed-fu plugin from GitHub .