Our Blog. We have some things we'd like to share.

Rails fixtures with models using set_table_name

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
Tagged:

6 Responses to “Rails fixtures with models using set_table_name”

  1. 1

    April 30th, 2007 @ 10:39 pm Chadwick responded:

    For schema names in fixtures, you can simply pass the fixture helper a string rather than a symbol. Ex:

    class UserTest

  2. 2

    May 25th, 2007 @ 7:47 am Aleksey Gureev responded:

    Thanks! Right what I was looking for!

  3. 3

    July 16th, 2010 @ 3:54 pm Nicolas Buduroi responded:

    Great information! Now, it would be great to have something similar for migrations.

  4. 4

    May 24th, 2012 @ 4:09 am Rails – changed a table name, now tests won't run | PHP Developer Resource responded:

    [...] http://www.missiondata.com/blog/systems-integration/80/rails-fixtures-with-models-using-set_table_na... [...]

  5. 5

    September 13th, 2012 @ 1:46 pm Michiel Sikkes responded:

    Wow thanks! I know this is a post from the past. But this just helped me fix my problems, Anno 2012 ;-)

  6. 6

    November 21st, 2012 @ 4:05 pm S responded:

    Thanks for saving my time!

Leave a Response

Cincinnati 513.298.1865

Virginia 7875 Promontory Court Dunn Loring, VA 22027

Kentucky 12910 Shelbyville Road Suite 310 Louisville, KY 40243 502.245.6756

© 2013 Mission Data