开发者

Why is this code not behaving transactionally?

I want to destroy all the questions to do with a particular user. Some questions are protected though and may prevent themselves from being destroyed and raise an exception.

I would expect the following code to destroy either all questions or none however it doesn't - if there is a protected question amongst the others it doesn't roll back the previous destroy actions - why开发者_开发问答 is this?

class User < ActiveRecord::Base
 ...

  Questions.transaction do
    # protected questions will raise a runtime exception
    Questions.destroy_all(:user_id => self.id)
  end
end


Grrr, just realised I'd hit this problem before and wasted a load of time then before figuring it out.

The issue is that the test is being done in RSpec which itself uses transactions and removes transactional functionality from the code as a result (n.b. anyone reading this from the RSpec team - it would be great to have a warning when parsing code that contains transactions - ty!).

In order to make the transaction work within RSpec wrap it in the following code:

describe "the set of cases you want to address" do

  # make sure this next line is contained within a describe block or it'll affect everything
  self.use_transactional_fixtures = false

  after(:each) do
    # destroy all objects you created (since RSpec won't roll them back for you)
    # use delete rather than destroy to force removal
    User.delete_all
    Question.delete_all
  end

  it "should not destroy any questions when one fails to be destroyed" do
    # assuming one of the questions throws an error on being destroyed
    expect{
      @user.destroy
    }.to change{ Question.all.count }.by(0)
  end
end

end

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜