読者です 読者をやめる 読者になる 読者になる

Programming log - Shindo200

イベント参加記録とプログラミング系の雑記

ActiveSupport::Callbacks を使ってメソッドに前処理を挟み込む

Rails の Controller には、アクションメソッドに前処理を挟み込むための before_action というメソッドが存在します。ActiveRecord などを継承していない普通の Ruby のクラスでも簡単に前処理を挟み込めるようにしたいと思う場面がありまして、便利なモジュールがないか調べたところ、ActiveSupport::Callbacks というモジュールを見つけました。このエントリでは、このモジュールの使い方を簡単に紹介していきます。

ActiveSupport::Callbacks

ActiveSupport::Callbacks

ActiveSupport::Callbacks は「あるコードが実行されることをきっかけにして、別の処理を呼び出す」という処理が簡単に定義できるようになるモジュールです。エントリの冒頭で話したように「あるメソッドに前処理を挟み込む」といった実装が簡単に作れるようになります。ちなみに、実行されるきっかけを「フック」、フックによって呼び出されるメソッド「コールバックメソッドと呼びます。

早速、ActiveSupport::Callbacks を利用した単純なクラスを定義し、処理を挟み込むことができていることを確認します。

class Entry
  include ActiveSupport::Callbacks
  define_callbacks :before_check
  set_callback :before_check, :before, :check

  def check
    puts 'Checking.'
  end

  def submit
    puts 'Submit entry.'

    run_callbacks :before_check do
      puts 'Submitting.'
    end

    puts "You've successfully submit."
  end
end

Entry.new.submit
# Submit entry.
# Checking.
# Submitting.
# You've successfully submit.

submit メソッドを呼び出したときの様子を見ると、run_callbacks ブロック内のコードが実行される直前で check メソッドが実行されていることがわかります。ActiveSupport::Callbacks を使うときに大事なことは次の3つです。

  • define_callbacks メソッドでフック名を定義しておく
define_callbacks :hooks_name
  • set_callback メソッドで「どのフック名の」「どのイベントをトリガーにして」「どのコールバックメソッドを呼び出すか」を定義しておく
set_callback :hooks_name, :before, :callback_mehotd
  • run_callbacks メソッドでフックが発生する処理を指定しておく
run_callback :hooks_name do
  /* 処理 */
end

使い方はわかりましたでしょうか。今回紹介した使い方以外に、set_callback メソッドに if というオプションを渡すことで「特定の条件に当てはまるときだけコールバックメソッドを呼び出す」ということもできるようになりますので、より詳しく知りたい方はぜひドキュメントをご一読ください。