0

In my Rails application, I have a method which copies many rows, and also goes on to copy down some of the parent-child relationships.

def merge
   params[:merge_rows].each do |merge_row|
      batch_detail = BatchDetail.find(merge_row)
      batch_detail.duplicate
      batch_detail.batch_id = batch.id
      batch_detail.save
   end
   render nothing: true
end

# BatchDetail.duplicate
def duplicate
  batch_detail = dup
  batch_detail.primer3_parameter = primer3_parameter.dup if primer3_parameter.present?
  primer3_outputs.each do |primer3_output|
    batch_detail.primer3_outputs << primer3_output.duplicate
  end
  batch_detail
end

Ideally, I would like to only save if all rows are successfully duplicated, and rollback all changes if any are unsuccessful.

Then I would like to report 200 or 500 via the render if successful or error.

port5432
  • 5,889
  • 10
  • 60
  • 97
  • 1
    Try [`transaction`](http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html). – D-side Jul 17 '15 at 18:56
  • possible duplicate of [Transaction Action with Ruby On Rails](http://stackoverflow.com/questions/933696/transaction-action-with-ruby-on-rails) – D-side Jul 17 '15 at 19:04

1 Answers1

1

wrap your ActiveRecord changes in a transaction block, if the end of the block is bypassed by some exception, all changes are rolled back.

begin
  ActiveRecord::Base.transaction do
    ...various transactions
    if (some_error_condition)
      raise
    end         
  end
  ...stuff to do if all successful
rescue
  ...stuff to do on failure
end
SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53