🌵

Railsのコールバックについて

2021/08/02に公開

Railsのコールバックについてよく分からない箇所があったので記録を残しておきます。

コールバックとは

モデルのCRUDなどのイベントのタイミングで特定の処理を呼び出すこと

モデルにコールバックメソッドを直接書く

app/models/memo.rb
class Memo < ApplicationRecord
  after_create :after_create_message #createアクション後に呼び出すメソッド名をシンボルで指定する

  private

  def after_create_message
    puts 'memo was created!!!!'            
  end
end
rails c
Memo.create
#=> 'memo was created!!!!'

コールバッククラスを別で作る場合

1.コールバッククラス内でインスタンスメソッドを定義する

app/models/memo.rb
class Memo < ApplicationRecord
  after_create MemoCallbacks.new #コールバックインスタンスを渡す
end
app/models/memo_callbaks.rb
class MemoCallbacks
  def after_create
    puts 'memo was created!!!!'
  end
end
rails c
Memo.create
#=> 'memo was created!!!!'

2.コールバッククラス内でクラスメソッドを定義する

app/models/memo.rb
class Memo < ApplicationRecord
  after_create MemoCallbacks #クラス名を渡す
end
app/models/memo_callbaks.rb
class MemoCallbacks
  def self.after_create
    puts 'memo was created!!!!'
  end
end
rails c
Memo.create
#=> 'memo was created!!!!'

コールバッククラスを作るとモデルインスタンスを渡すことができる

上記の例だとインスタンス生成時にコンソールに文字列を表示しているだけですが、インスタンスのカラム名などを使いたい場合の方が多いと思います。

1.コールバッククラス内でインスタンスメソッドを定義する

app/models/memo.rb
class Memo < ApplicationRecord
  after_create MemoCallbacks.new
end
app/models/memo_callbaks.rb
class MemoCallbacks
  def after_create(memo) # 引数でモデルインスタンスを渡せる
    puts "title is #{memo.title}"
  end
end
rails c
Memo.create(title: 'METAFIVE') 
#=> "title is METAFIVE"

2.コールバッククラス内でクラスメソッドを定義する

app/models/memo.rb
class Memo < ApplicationRecord
  after_create MemoCallbacks
end
app/models/memo_callbaks.rb
class MemoCallbacks
  def self.after_create(memo) # 引数でモデルインスタンスを渡せる
    puts "title is #{memo.title}"
  end
end
rails c
Memo.create(title: 'METAATEM') 
#=> "title is METAATEM"

多分これが一番使い勝手がいい

最初after_create MemoCallbacks.newみたいなコードを見て、インスタンスを渡しているだけで何もしていないのでは?と勘違いしてしまっていたけど継承元のActive Recordに定義されているみたいでした。Railsは学べば学ぶほど便利だな〜。

参考: Active Record コールバック - Railsガイド

Discussion