The blog of Rahoul Baruah from 3hv Ltd

What's going on?

My name is Rahoul Baruah (aka Baz) and I'm a software developer in Leeds (England).

This is a log of things I've discovered while writing software in Ruby on Rails. In other words, geek stuff.

However, I've decided to put this blog on ice - I would ask you to check out my business blog here (or subscribe here).

15 March, 2007

Filling your database with standing data

I'm just adding a new class to my application and it needs a pre-populated list of entries - standing data that will always need to be there. This is pretty easy to set up using migrations and a bit of ERb - and it even works in your test fixtures.

Firstly, create a new migration and define your model. However, do not run the migration yet.
Open your model and add a new class method (I'm using a Colour object for this example):


def self.build_defaults
build('Red')
build('Green')
build('Blue')
end

private

def build(name)
Color.create(:name => name) unless Colour.find_by_name(name)
end


Simple enough - your build_defaults lists the standing data and build creates it, unless it already exists.

Now go back to your migration file and change it like so:


def self.up
create_table :colours do | t |
t.column :name, :string
end

Colour.build_defaults
end


Now, when you run the migration it is automatically populated with Red, Green and Blue.

However, there's a problem. When you run your tests, the database structure is copied but no data. You need fixtures.

Of course, you could just add the fixtures into colours.yml by hand. Easy enough for colours but what if you have something more complex? And if you add new standing data you have two places to make the change - in your model and in your fixtures.

There is an easy answer - fixture files are YAML and therefore can have ruby code (ERb) embedded in them - just like your views.

So edit colours.yml to look like this:


<% Colour.build_defaults %^gt;
<% Colour.find(:all).each do | colour | %>
<%= "#{colour.name.gsub(' ', '_')}" %>:
id: <%= colour.id %>
name: <%= colour.name %>
<% end %>


The first line builds your defaults into the test database.
The next line goes through all colours in the database and for each one generates your fixtures YAML. Firstly the fixture name - this is the colour name (with underscores instead of spaces). And next (watch the indentation) the id and name fields.

Once more, Rails makes it easy.

No comments:

eXTReMe Tracker