Does Rails automatically wrap non-schema-change migrations in a transaction?

Viewed 394

I have created a migration in a Rails application:

class UpdateDefaultValues < ActiveRecord::Migration[5.2]
  def up
    OrderType.where(:category =>"reclamation").update_all(:prevent_delivery => false)
    InvoiceType.where(:category =>"reclamation").update_all(:send_automatically => true)
  end

  def down
    OrderType.where(:category =>"reclamation").update_all(:prevent_delivery => true)
    InvoiceType.where(:category =>"reclamation").update_all(:send_automatically => false)
  end
end

Notably, this migration does not change the database schema; it performs data changes only.

I was wondering: Does rails execute the up and down methods within SQL transactions automatically, or do I need to wrap the two updates within own transaction, to make sure that the migration will update all or nothing?

1 Answers

Rails does not put it in a Transaction block. It will just exit if one of that fails. If you want both to happen no matter what then as you have said you will have to put in a ActiveRecord::Base.transaction block. In your case it should be something like below -

class UpdateDefaultValues < ActiveRecord::Migration[5.2]
  def up
    ActiveRecord::Base.transaction do
      OrderType.where(:category =>"reclamation").update_all(:prevent_delivery => false)
      InvoiceType.where(:category =>"reclamation").update_all(:send_automatically => true)
    end
  end

  def down
    ActiveRecord::Base.transaction do
      OrderType.where(:category =>"reclamation").update_all(:prevent_delivery => true)
      InvoiceType.where(:category =>"reclamation").update_all(:send_automatically => false)
    end
  end
end
Related