Tragically L33T
msgbartop
Hip? Who talks like that?
msgbarbottom

26 Jun 06 Keeping Fixtures DRY in Trees

So I am working on a Rails project that revolves around an acts_as_tree using single table inheritence (STI). I got tired REALLY quickly with figuring out what id to use for each parent_id field. I figured that in the spirit of Don’t Repeat Yourself I would come up with a DRY way to specify the parents that did not require reapplying the id’s to the fixtures when I change things.

Since the YAML fixtures in ruby are parsed through eRb first, I thought I would give this a try. I made a file called thing_data.yml with my fixtures like so:


root:
  name: root item
  parent_id:
first_branch:
  name: a branch
  parent_id: root
second_branch:
  name: another branch
  parent_id: root
a_leaf:
  name: a leaf on the wind
  parent_id: first_branch

Notice the utter lack of ids. Now with a little eRb magic we put the following in the yaml file you plan to load as your fixture. Lets call it thing.yml:


<%

id_key = 1

data = YAML.load_file(
  File.expand_path(
    File.dirname( __FILE__ ) + '/test/fixtures/thing_data.yml'
  )
)

@final = Hash.new
data.each {|key, value|

  record = Hash.new

  record.update( value )
  record['id'] = id_key
  record[ 'created_at' ] = Time.now.strftime("%Y-%m-%d %H:%M:%S")
  record[ 'updated_at' ] = Time.now.strftime("%Y-%m-%d %H:%M:%S")

  @final[ key ] = record

  id_key = id_key.next
}  

thing_ids = Hash.new

@final.each { |key, value|
  thing_ids[ key ] = value[ 'id' ]
}

@final.each { |key, value|
  value[ 'parent_id' ] = thing_ids[ value[ 'parent_id' ] ]
}
%>
<%= @final.to_yaml %>

To test, run erb thing.yml and see your output. No more hand coding of ids and hoping you didn’t put something in the wrong place!

[tags]ruby, rails, dry, fixtures, testing[/tags]



Leave a Comment