Bug in fixtures.rb Fixtures.initialize, line 274
Scenario:
We would like to use ActiveRecord, fixtures and unit tests to test against an existing database.
Error:
@table_name is not set correctly when the underlying table for the model is not the Rails default.
Running a unit test with a fixture will error out in the DELETE FROM <table name> sql statement because <table name>
will be incorrect.
Steps to reproduce:
1) Set up empty development and testing databases.
2) Run setup_table.rb (included) - this will create a table called nowplaying.
3) Create a rails application
4) Create a model for the nowplaying table:
script/generate model --skip-migration NowPlaying
5) Modify the model created in step 4 so that it points to the table created in step 2.
from now_playing.rb:
class NowPlaying < ActiveRecord::Base
set_table_name 'nowplaying'
set_primary_key 'NPId'
end
6) Add a fixture to now_playings.yml
from now_playings.yml:
one:
EPlayListId: <%= rand(10000) %>
EBubbleId: <%= rand(10000) %>
ETrackId: <%= rand(10000) %>
EStoreId: <%= rand(100) %>
PlayedDate: <%= 1.day.ago.strftime('%m/%d/%Y %H:%M:%S') %>
ContentType: 1
7) Set up the test database:
rake db:test:prepare
8) Run the default unit test file for our model:
ruby now_playing_test.rb
It should error out saying that the relation "now_playing" does not exist.
Observations:
Upon entering the Fixtures.initialize method,
table_name is now_playings (same as fixture file)
class_name is nil
After this line:
@class_name = class_name
(ActiveRecord::Base.pluralize_table_names ? @table_name.singularize.camelize : @table_name.camelize)
We have,
@class_name = NowPlaying (correct). note, @class_name.class == String
Next, we try to set @table_name (first try):
@table_name = ActiveRecord::Base.table_name_prefix + @table_name + ActiveRecord::Base.table_name_suffix
@table name is unchanged. I don't set those class vars
Second try:
@table_name = class_name.table_name if class_name.respond_to?(:table_name)
Here is the problem. class_name is nil so it will not respond to :table_name so the table_name of the model will never be chosen
I have tested the patch I am submitting against the trunk version of activerecord. All test pass: 1098 tests, 4177 assertions, 0 failures, 0 errors