4

私はこのドメインモデルを持っています:ユーザーはアイテムのグループを持っており、アイテムの状態は検証に失敗する可能性があります。

検証は正常に機能し、を使用すると例外が呼び出されることもありますsave!

私のコントローラーには、次のものがあります。

@user.items() << item

if @user.save
  render :json => {}, :status => :ok
else
  render :json => {:status => :error, :errors => item.errors}, :status => :bad_request
end

最初のPOSTは成功し、2番目のPOSTは失敗しますが、インデックスにヒットすると、2番目のトランザクションがロールバックされなかったかのように、2つのオブジェクトが表示されます。何が起こっている?

私のテストはこれです:

  post :create
  post :create
  get :index
  ActiveSupport::JSON.decode(response.body).length.should == 1

編集:サーバーを実行している場合でも、トランザクションはロールバックされていません(sqlite3)。

4

2 に答える 2

3

コレクションにアイテムを追加すると、すぐに保存されます(ユーザーが保存されていない場合を除く)。保存の呼び出しは独自のトランザクションを作成し、それがロールバックされるものであり、アイテムが保存されるトランザクションではありません

明示的に作成することで、すべてを同じトランザクションに強制することができます。

begin
  User.transaction do
    @user.items << item
    @user.save!
    render :json => {}, :status => :ok
  end
rescue ActiveRecord::RecordInvalid
  render :json => {:status => :error, :errors => item.errors}, :status => :bad_request
end
于 2013-02-03T17:17:24.563 に答える
2

テストでネストされたトランザクションの問題が発生しているようです。

Postgres用のRubyドライバーがネストされたトランザクションを処理するとは思わないので、外部トランザクションのスコープのみを取得します。トランザクションフィクスチャを有効にしている場合は、テスト実行をラップする外部トランザクションがあります。これは、テスト対象のコントローラーが2番目の内部トランザクションを作成し、それをロールバックしようとした場合、正しい動作が得られない可能性があることを意味します。

rspecでトランザクションをオフにすることで、トランザクションの干渉を確認できます。

RSpec.configure do |config|
  config.use_transactional_fixtures = false
end
于 2013-02-02T19:07:34.343 に答える