LoginSignup
275
245

More than 5 years have passed since last update.

Railsのcallbackについて調べた

Last updated at Posted at 2014-08-05

色々詰まったので勉強がてらまとめてみた
Railsのバージョンは3.2

callbackとは

  • オブジェクトの生成・更新・削除のタイミングで呼び出されるメソッド
  • トリガとなるイベント(create, saveなど)の前後に登録可能
  • トリガに対してメソッドを共通化できて便利

callbackの順番

create,update,find,destroyでまとめた
それぞれ上から順番に実行される

create

create_test.rb
hoge = Hoge.new(name: "hoge")
#initialize
after_initialize #newメソッドで生成したときのみ
hoge.save!
#BEGIN TRANSACTION
before_validation
#validation
after_validation
#ROLLBACK
after_rollback   #validationに失敗した時のみ
before_save
around_save
before_create
around_create
#INSERT INTO "hoges"
after_create
after_save
# COMMIT
after_commit

update

update_test.rb
hoge.update(name: "fuga")
#BEGIN TRANSACTION
before_validation
#validation
after_validation
#ROLLBACK
after_rollback   #validationに失敗した時のみ
before_save
around_save
before_update
around_update
#UPDATE "hoges" SET
after_update
after_save
# COMMIT
after_commit

find

find_test.rb
hoge = Hoge.first
# SELECT hoges.* FROM 
#initialize
after_initialize
after_find

destroy

destroy_test.rb
hoge.destroy
#BEGIN TRANSACTION
before_destroy
around_destroy
#DELETE from hoges
after_destroy
# COMMIT
after_commit

changed?が使用できるcallback

要素の変更を確認できるchanged?メソッドが使えるcallbackを調べた。

changed_method.rb
# ここから→
before_validation
after_validation
after_rollback
before_save
around_save
before_update
around_update
after_update
after_save
# →ここまでは使える
after_commit #使えない

changed?系のメソッド一覧

change_series.rb
hoge = Hoge.find_by(name: hoge)
hoge.name  = fuga

#objectが変更されたか?
hoge.changed? #=>true
#指定要素が変更されたか?
hoge.name_changed? #=>true
#指定要素がhogeからfugaに変更されたか?
hoge.name_changed?(from: hoge, to:fuga) #=>true
#指定要素の変更前の値?
hoge.name_was #=>”hoge”
#指定要素の変更前後の値
hoge.name_change #=>[“hoge”, “fuga”]
#変更要素名
hoge.changed #=>[“name”]

accepts_nested_attributes_forを使った時のcallbackの順番

上から順番に処理されます。
ややこしいのであんまり使いたくない。

親:before_validation
子:before_validation
子:after_validation
親:after_validation
親:before_save
親:around_save
親:before_xxx
親:around_xxx
子:before_save
子:around_save
子:before_xxx
子:around_xxx
子:after_xxx
子:after_save
親:after_xxx
親:after_save

around_xxxの使いドコロ

around_xxxの使いドコロがよく分からなかったので調べてみた。
トリガーの前後で処理を定義できるっぽい。便利そう。

around_xxx.rb
def around_save
  # 何かしらの処理
  yield #saves
  # 何かしらの処理2
end
275
245
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
275
245