Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are `save` and `save!` the only methods that persist ActiveRecord objects?

I'm trying to debug some code. One odd part is that a before_save callback is getting called twice, though I'm only intending to save the object once.

To trace how this is happening, I've defined these methods in the class:

%w[save save!].each do |method_name|
  define_method(method_name) do |*args|
    puts "who called '#{method_name}'? #{caller.first}"
    super(*args)
  end
end

From this output, I only see one persistence call.

I believe that save and save! are the only methods that cause ActiveRecord to persist the objects. As far as I know, other persistence methods rely on one of these two; for example, update_attributes calls save, update_attributes! calls save!, etc.

Do any methods persist an ActiveRecord object without calling save or save!?

(I'm using ActiveRecord 3.2.13)

Update

Looking in the Rails source for 3.2.13, both save and save! call the private method create_or_update to do their work. I used git grep to look for other occurrences of create_or_update and only found tests and something in callbacks.rb that wraps it.

create_or_update in turn, relies on klass.connection.update and self.class.unscoped.insert.

So perhaps the question is whether anything other than create_or_update persists an ActiveRecord object.

like image 868
Nathan Long Avatar asked Jun 07 '13 12:06

Nathan Long


1 Answers

Looking at ActiveRecord 3.2.13 callbacks.rb, line 264. The save callbacks are triggered whenever create_or_update is called. That method is only called by save and save!. update_column bypasses create_or_update and uses update_all instead. first_or_create calls create, which calls save.

I'd be looking in two places: 1. Does the save trigger a save in an associated record that attempts to save the original model again? If so, I'd expect the save method to get called again, so likely not this. 2. Are you sure that the before_save is what is getting called? Assuming you have "before_save :do_something", and do_something is getting called twice. Is anything calling :do_something outside of the context of the save? Or another before_save callback calls :do_something in addition to the callback?

like image 104
davidfurber Avatar answered Sep 24 '22 19:09

davidfurber