August 9, 2016
This blog is part of our Rails 5 series.
In Rails, for setting up test data we use fixtures. Fixtures are written as YAML
files placed in test/fixtures
directory in the Rails app.
The model name of a fixture is automatically picked up from the fixture file name.
Generally in Rails, the model name and table name follow a strict convention.
The table for User
model will be users
. By this convention, the fixture file
for User
model is test/fixtures/users.yml
.
But sometimes model names do not match directly with the table name. When we are building on top of a legacy application or we have namespacing of models, we might run into this scenario. In such cases detection of model name from fixture file name becomes difficult.
When automatic detection of model name from fixture file name fails, we can specify the table name using the set_fixture_class method. Take a look at our older blog for an example of how to do this.
One drawback of using this approach is that, the model name set using
set_fixture_class
is available only in the context of tests. When we run
rake db:fixtures:load
to load the fixtures, the tests are not run, and the
fixture file is not associated with the model name we set using
set_fixture_class
. This will cause failure to load the fixtures correctly.
In Rails 5 a new key is added to specify the model name for a fixture file.
Let us consider the example where our table was named morning_appts
, and we
used a more appropriately named model MorningAppointment
to represent this
table.
We can now set the table name in our fixture file
test/fixtures/morning_appts.yml
as follows :
_fixture:
model_class: MorningAppointment
standup:
name: Standup
priority: 1
The special key _fixture
in the fixture file is now used to store metadata
about the fixture. model_class
is the key we can use to specify the model name
for the fixture.
We can now use this fixture to load test data using the rake task
rake db:fixtures:load
as well.
Happy Testing!
If this blog was helpful, check out our full blog archive.