Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Railsのcallbackについて調べた

More than 1 year has passed since last update.

色々詰まったので勉強がてらまとめてみた
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
atrae
People Techカンパニーとして、転職サイトGreen, ビジネスマッチングアプリyenta, 組織改善プラットフォームwevoxなどのサービスを運営。全ての社員が誇りを持てる組織と事業の創造にこだわり、関わる人々がファンとして応援したくなるような魅力ある会社であり続けることを目指しています。
https://atrae.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away