Quantcast
Channel: Mission Data Blog » darrend
Viewing all articles
Browse latest Browse all 10

Rails fixtures with models using set_table_name

$
0
0

If you have a model that uses set_table_name you may hit a snag when trying to use fixtures and unit tests. The solution is twofold: name the fixture file using the legacy table name, and use the set_fixture_class method in your unit test. I coudn’t find this method mentioned in Agile Web Development with Rails, and there’s only a brief mention on the rubyonrails.com site. Still, some web searches turned up the answers.

Here is a simple example:

We’ll start with a table named libris_book that contains book entries. The name libris_book won’t really fly with the Rails pluralized table name approach. It’s easy, however, to fix that disconnect in the model:

class Book < ActiveRecord::Base
  set_table_name 'libris_book'
end

Let’s take a look at our data:

~/src/libris$ script/console
Loading development environment.
>> Book.count
=> 1230

Good enough. Now, we’ll be good little coders and write some unit tests using fixtures. We’ll create a fixture file and our test class:

books.yml

test_book:
  title: Life in Lawrenceburg
  author: Darren Day

book_test.rb

require File.dirname(__FILE__) + '/../test_helper'

class BookTest < Test::Unit::TestCase
  fixtures :books

  def test_fixtures
    assert_equal(2,Book.count)
    test_book = books(:test_book)
  end
end

Looks good, but it won’t work!

~/src/libris$ rake test
(in /home/darrend/src/libris)
/usr/local/bin/ruby -Ilib:test "/usr/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader.rb" "test/unit/book_test.rb"
Loaded suite /usr/local/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake/rake_test_loader
Started
E
Finished in 0.01133 seconds.

  1) Error:
test_fixtures(BookTest):
ActiveRecord::StatementInvalid: Mysql::Error: Table 'libris_test.books' doesn't exist: DELETE FROM books
...

Ugh. That doesn’t look pretty. After some googling around the following comes together

  • Rename books.yml to libris_book.yml. The fixture yaml file has to share the same name as the database table name.
  • Change the fixtures declaration to fixtures :libris_book.
  • Use set_fixture_class to connect the fixture to the model class.

Here is our new and improved book_test.rb file:

require File.dirname(__FILE__) + '/../test_helper'

class BookTest < Test::Unit::TestCase
  set_fixture_class :libris_book => Book
  fixtures :libris_book

  def test_fixtures
    assert_equal(2,Book.count)
    test_book = libris_book(:test_book)
  end
end

Viewing all articles
Browse latest Browse all 10

Trending Articles