views:

49

answers:

3

In rails 2 there was a private method on active_records called create_without_callbacks which you could call to save a record into the database without triggering the callbacks associated with that object. This method has disappeared in rails 3, is there any way to achieve the same thing?

+1  A: 

You are preventing certain business logic from happening when you'd call create_without_callbacks. Consider removing the callbacks if they are not needed, or use the :if and :unless options to trigger the callback only when needed.

Ariejan
When I'm unit testing an object that depends on another I often want to mock out the dependency. Unfortunately, if I do that active_record complains that the mock isn't of the correct type. In rails 2 I got around this by using factory girl to create what were effectively stubs of the correct type. I added a factory girl strategy that inserted a record using the create_without_callbacks method as they were irrelevant.
opsb
I understand, but that way you wouldn't be testing agains 'real life' objects. So, essentially you are not testing your application code. I always use Blueprint or FactoryGirl to create valid objects, including callbacks.
Ariejan
I use cucumber to do integration testing. When I'm unit testing the only 'real' object that I care about is the one I'm testing.
opsb
A: 

I don't know if all of this still work in R3, at least in 2.3.8 they did.

if it is just one attribute then

self.update_attribute(:attribute, value)

If it is multiple attributes on one object

self.update_attributes({:attribute => value})

You can also update all records with some conditions

update_all( "category = 'authorized' approved = 1, author = 'David'" )

The last one I just took from the rails API, I think it doesn't invoke callbacks but I'm not for sure on that.

Sam
You cannot call `update_attributes` on an unsaved object. The goal is to create a new object without calling the callbacks.
Ariejan
yeah, I didn't see the create in the questions.
Sam
A: 

Having looked at the source for rails3 it seems callbacks are added in such a way that the model.save method doesn't actually know about them.

The solution I've gone for is to mock out Model.find and return an instance that hasn't been saved. This is actually how unit tests should be done and they run faster to boot.

If you are interested in finding a hack I suggest you look at

  • rails3/activesupport/lib/active_support/callbacks.rb
  • rails3/activemodel/lib/active_model/callbacks.rb
  • rails/activerecord/lib/active_record/callbacks.rb

in that order.

opsb