Trey Connell

January 19, 2009 | In: Development, Ruby on Rails

Fixtures and Model Associations in Ruby on Rails

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??

Comment Form

Tradeomics

Twitterings

Recent Comments

Buy Awesome T-Shirts!

I hate pants t-shirt