web-dev-qa-db-ja.com

around_actionコールバックはどのように機能しますか?説明が必要です

私は、around_actionについてひどく混乱しています。それらはどのように機能しますか?誰かが私に彼らがどのように機能するかの例/説明を提供してもらえますか?

これは私のアジャイルWeb開発4の本からの引用です。

コールバックの周りはアクションの実行をラップします。アラウンドコールバックは2つの異なるスタイルで記述できます。最初の例では、コールバックはコードの単一のチャンクです。そのコードは、アクションが実行される前に呼び出されます。コールバックコードがyieldを呼び出すと、アクションが実行されます。アクションが完了すると、コールバックコードの実行が続行されます。したがって、yieldの前のコードはbefore actionコールバックのようなものであり、yieldの後のコードはafter actionコールバックです。コールバックコードがyieldを呼び出さない場合。アクションは実行されません。これは、アクション前のコールバックがfalseを返すのと同じです。

これを読んだとき、私はそれを手に入れました。 Railsガイドからの例です

class ChangesController < ApplicationController
  around_action :wrap_in_transaction, only: :show

  private

  def wrap_in_transaction
    ActiveRecord::Base.transaction do
      begin
        yield
      ensure
        raise ActiveRecord::Rollback
      end
    end
  end
end

ここで何が起こっているのでしょうか? ActiveRecord :: Base.transactionは「前」の部分から始まり、「後」の部分としてActiveRecord :: Rollbackを発生させますか?この方法は何をもたらすのですか?それはショーですか?最後に、yieldメソッドが失敗してコールバック全体が失敗する原因は何でしょうか?それはショーアクションのレンダリングでしょうか?わかりません。助けてください。

21
Dan Rubio

私の理解は以下の通りです:

begin
    # Do before action...
    logger.info 'I am the before action'

    # Do the action, which is passed as a block to your "around filter"
    # Note that if you were to delete this line, the action will never be called!
    yield

    # Do after action...
    logger.info 'I am the after action'
ensure
    raise ActiveRecord::Rollback
end
24
Damon Yuan

Around_callbackのキーはyieldです。 wrap_in_transactionの例の場合:yieldはshowアクションに置き換えられます。 showが終了すると(包括的にレンダリング)、wrap_in_transactionは続行され、ロールバックを実行します。

Rails guides で見つけることができます:

たとえば、変更に承認ワークフローがあるWebサイトでは、管理者はそれらを簡単にプレビューでき、トランザクション内で適用するだけです。..アラウンドフィルターはレンダリングもラップすることに注意してください。特に、上記の例で、ビュー自体がスコープなどを介してデータベースから読み取る場合は、トランザクション内で読み取り、プレビューするデータを提示します。」

つまり、showのユーザーは、ロールバック前に情報を見ることができます(この場合、showは、情報アクションであるため、ロールバックが必要な一種の更新を実行している必要があります)。

yieldを使用してアクションを中央に配置するのは、around_callbackが1つのメソッドのみのbeforeコールバックとafterコールバックであると考えることができます。

19
Alejandro Babio