How can I rollback a rails save/transaction?

chris P picture chris P · Feb 21, 2015 · Viewed 12.6k times · Source

In my controller I have some code like...

...
if user.save
    something = Something.where("thing = ?", thing)
    if !(something.nil?)
        render json: { something: something }
    else
        #I WOULD LIKE TO ROLLBACK THE user.save HERE
    end
else
    render json: { error: user.errors.full_messages }, status: :bad_request
end

I have tried

raise ActiveRecord::Rollback, "Could not create new User, Something was not found."
render json: { error: "Could not create new User, Something was not found"}, status: :unprocessable_entity

in place of the ROLLBACK COMMENT area above, but this does not work. The user.save ends up going through. It spits something out to 'rails s', but it does not rollback the last transaction.

Answer

Mohammad AbuShady picture Mohammad AbuShady · Feb 21, 2015

If you want to use a transaction in the same sense you mentioned you could do something like this

User.transaction do
  if user.save
    something = Something.where("thing = ?", thing)
    if !(something.nil?)
      render json: { something: something }
    else
      raise ActiveRecord::Rollback
    end
  else
   render json: { error: user.errors.full_messages }, status: :bad_request
  end
end

Not sure if wrapping the response inside the transaction would work or not, but you'll need to test that.

PS: These two lines

something = Something.where("thing = ?", thing)
if !(something.nil?)

Are just equivalent to

if Something.exists?(thing: thing)