Trancey
Trancey

Reputation: 709

atomic transaction not working - ruby rails

So I am trying to achieve atomicitiy in while doing my saves (which are essentially updates on each rows).

params[:player_types].each do |p_type_params|
  if p_type_params[:id]
    player = @player_types.find(p_type_params[:id])
    player.assign_attributes(p_type_params)
    @player_types << player
  end
end

ActiveRecord::Base.transaction do
  @player_types.each do |player_type|
    if player_type.save
      "DO Something.."
    else
      "DO something else.."
      errors = true
    end
  end
end

Inspite of saving withing the transaction block, I can see partial saves also i.e. one of the rows get updated and the erroneous one does not (obviously) where as I would have wanted the updated row to be rolled back since there was atleast one row that could not be updated due to an error. Is my interpretation of transaction block correct in this case? How do I achieve an atomic save in my case?

EDIT: The model validates for uniqueness of one of the columns, which would be the reason for failing to update in the Database at this point.

Upvotes: 0

Views: 841

Answers (1)

Todd Agulnick
Todd Agulnick

Reputation: 1995

You need to raise an error inside your transaction block to abort the transaction; setting errors doesn't impact the transaction.

For instance:

ActiveRecord::Base.transaction do
  @player_types.each do |player_type|
    if player_type.save
      "DO Something.."
    else
      "DO something else.."
      raise "save failed!"
    end
  end
end

The more conventional way of doing this, of course, is to use save! which raises an exception for you when it fails:

ActiveRecord::Base.transaction do
  @player_types.each do |player_type|
    player_type.save!
  end
end

If you really need to "DO Something" on failure (besides aborting the transaction), you'll have to use the first method.

Upvotes: 1

Related Questions