I’m forcing myself to write tests for all my development on the movie site. (We still haven’t chosen a final name for it – lame…) Once of the things I love the most in Rails is Fixtures.
Fixtures allow you to setup your test data in YAML or CSV. That data is then loaded when you run your functional, unit, and integration tests. You can also just load the data outside of any testing effort by running ‘rake db:fixtures:load’. I can’t even tell you how handy that is. I can populate my development site with data and starting banging around on pages that actually work – with real data – in the blink of an eye. Got a bug? Fix it and reload. It’s niiiice.
As I started building my fixtures, I started with the easy models first. Movie is an obvious choice. This is my movies.yml file:
movie1:
title: The Dark Knight
director: Christopher Nolan
release_date: 2008-07-18
description: Batman Gordon and Harvey Dent are forced to deal with the chaos
starring: Christian Bale
rating: PG-13
product_url: http://www.amazon.com
thumbnail_path: /images/movies/thumbs/the-dark-knight.jpg
image_path: /images/movies/full_size/the-dark-knight.jpg
number_of_reviews: 5
avg_rating: 8.8
featured: 1
permalink: the-dark-knight
movie2:
title: Tropic Thunder
director: Ben Stiller
release_date: 2008-08-13
description: Goofy movie with lots of bid-budget actors
starring: Ben Stiller, Robert Downey Jr., Jack Black
rating: R
product_url: http://www.amazon.com
thumbnail_path: /images/movies/thumbs/tropic-thunder.jpg
image_path: /images/movies/full_size/tropic-thunder.jpg
number_of_reviews: 10
avg_rating: 7.5
permalink: tropic-thunder
Now I have two movies that I can load at any time. But wait. My site is also going to have Movie Reviews in it. Each review be associated with one and only one Movie. In my Movie Review model, that relationship is established by the belongs_to :movie statement at the top of the class. I also have a has_many :movie_reviews statement at the top of my Movie class.
MovieReview has a movie_id column that references the Movie it belongs to. But how can I represent that in my movie_reviews.yml file where I’m entering data? I won’t know the movie_id assigned to my new movies, and I don’t want to have to hardcode it into my movie_reviews.yml records anyway. Enter more Rails magical deliciousness.
Because of the relationship setup in the models, Rails let’s you refer to the record names that you’ve specified in order to relate certain data rows across tables. Here’s my movie_reviews.yml file:
review1:
title: My great movie review
movie: movie1
rating: 7
review: NO SPOILERS. I saw an advanced showing of this 2 nights before it came out.
found_useful: 5
review2:
title: Tropic Blunder
movie: movie2
rating: 5
review: Great Premise! Started out hilarious...funny 1st half...Robert Downey was great!
found_useful: 2
Notice I have specified the movie that each relates to by specifying movie: movie1 and movie: movie2 in each record. Those movie names are the same that I specified in movies.yml. When I run rake db:fixtures:load, I see that the movie_id column in the movie_reviews table has been populated with the correct movie_id from the movies table in each of the two rows inserted.
How cool is that??