Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do fixtures trigger model callbacks?

Tags:

Say I have a User model with the following code in User.rb:

before_create :create_dependencies after_create :build_inbox 

And I also have a users.yml file with a bunch of user fixtures defined in it.

When I run rake db:fixtures:load, it doesn't appear to trigger the callbacks.

  1. Is this how it is expected to work? If so, why did they design it this way?
  2. Is there a way to force the triggering of the callbacks when loading fixtures?
like image 568
cakeforcerberus Avatar asked Aug 03 '09 15:08

cakeforcerberus


People also ask

What is the benefit of using factories over fixtures?

It has a benefit of clarity and low overhead. Like I said above, I've definitely used factories more than fixtures. My main reason is that when I use factories, the place where I specify the test data and the place where I use the test data are close to each other. With fixtures, on the other hand, the setup is hidden.

What are fixtures rails?

Fixtures are data that you can feed into your unit testing. They are automatically created whenever rails generates the corresponding tests for your controllers and models. They are only used for your tests and cannot actually be accessed when running the application.

What are RSpec fixtures?

Fixtures allow you to define a large set of sample data ahead of time and store them as YAML files inside your spec directory, inside another directory called fixtures. When you're test sweep first starts up RSpec will use those fixture files to prepopulate your database tables.

What are callbacks in rails?

Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.


2 Answers

Is this how it is expected to work? If so, why did they design it this way?

Yes, fixtures do not use callbacks. I'm assuming this is for performance reasons. It is quicker to load the data straight into the database without instantiating the model.

Is there a way to force the triggering of the callbacks when loading fixtures?

Not that I know of. You have a couple options. One is to build your fixtures as if the callbacks were already triggered. That is, manually create the data that the callbacks would. For example, if you have a callback which hashes a user's password you would need to hash the password manually and then store that hash in the fixture.

The second solution (and highly recommended!) is to use factories. Factories do trigger callbacks and allow you to use virtual attributes, etc. This is because they do instantiate the model each time. One popular gem is Factory Girl. Another one to try is Machinist. I have also created a Railscasts episode on the topic.

like image 140
ryanb Avatar answered Oct 13 '22 00:10

ryanb


I have this problem as well. Our app calculates some totals before_save so it doesn't have to be done on the fly. Makes reporting faster and cuts out a few joins on certain reports.

In the tests for those objects we manually run the callbacks like this:

before do   order.perform_callbacks end 

This works out well because it doesn't run all the time so other tests don't suffer.

We are using minitest and fixtures btw.

like image 21
jacklin Avatar answered Oct 13 '22 00:10

jacklin