I am trying to execute two things inside a transaction and I'm not sure how I should test it in rspec. My code looks something like this:
Implementation:
def method
begin
ActiveRecord::Base.transaction do
...some implementation...
model1.save!
model2.save!
end
rescue => e
exception_info = {:class => e.class, :message => e.message, :backtrace => e.backtrace}
@logger.warn("Error. Rolling back.", :exception => exception_info)
end
end
Tests:
it "model1 object is not created if model2 fails to save" do
Model1.any_instance.should_receive(:save).and_raise("model1 save error!!")
method
Model2.all.should == []
end
it "" do
Model2.any_instance.should_receive(:save).and_raise("model2 save error!!")
method
Model1.all.should == []
end
I want both the models to be saved or none. My rspec tests check both the cases but I keep getting errors. If I add (:requires_new => true) to the transaction, it works. I thought it was meant for nested transactions, not something like this. Am I missing something?
ActiveRecord transactions only rollback if an exception is raised. Otherwise they persist whatever records were successfully created.
In your case, you want to use save!
instead of save
to interrupt the transaction. This will raise an ActiveRecord::RecordInvalid
exception which you need to rescue and handle.
begin
ActiveRecord::Base.transaction do
...some implementation...
model1.save!
model2.save!
end
rescue ActiveRecord::RecordInvalid
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.