Почему этот код не ведет себя транзакционно? - PullRequest
3 голосов
/ 03 августа 2011

Я хочу уничтожить все вопросы, связанные с конкретным пользователем. Однако некоторые вопросы защищены и могут предотвратить их уничтожение и вызвать исключение.

Я бы ожидал, что следующий код уничтожит либо все вопросы, либо ни одного, однако это не так - если есть защищенный вопрос среди других, он не откатывает предыдущие действия уничтожения - почему это так?

class User < ActiveRecord::Base
 ...

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

1 Ответ

2 голосов
/ 04 августа 2011

Гррр, только что понял, что я столкнулся с этой проблемой раньше и потратил кучу времени, прежде чем понять это.

Проблема заключается в том, что тест выполняется в RSpec, который сам использует транзакции и в результате удаляет транзакционную функциональность из кода (если кто-то читает это из команды RSpec - было бы здорово получить предупреждение, когдакод синтаксического анализа, содержащий транзакции - ty!).

Чтобы транзакция работала в RSpec, оберните ее следующим кодом:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...