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.
Rails transactions are tied to one database connectionAnd as long as the transaction block is running this one database connection is open. So try to do as little as needed inside the transaction block, otherwise you will be blocking a database connection for more time than you should.
Transactions in ActiveRecord We're calling the transaction method on the ActiveRecord::Base class and passing it a block. Every database operation that happens inside that block will be sent to the database as a transaction.
You need to wrap the code in a transaction for the rollback to work properly. Here's the documentation: http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
Something like
ActiveRecord::Base.transaction do
# the code from your question
end
The key is that both the user.save
call (which modifies the DB) and the raise ActiveRecord::Rollback
call need to be in that block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With