概要
ActiveRecord | Callback
詳細
Active Recordはそのライクサイクルに様々なフックが用意されています。
Callback はクラスマクロ形式で設定する。例えば
class User < ActiveRecord::Base validates :login, :email, presence: true before_validation :some_hook protected def some_hook logger.info "some_hook" end end
とすれば、 validationの直前に「some_hook」というログが出力されます
サンプル
save, create, update, destroy のフックの呼び出しを確認します。
テーブル定義
CREATE TABLE "articles" ( "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "text" text, "created_at" datetime, "updated_at" datetime );
動作確認用モデル
class Article < ActiveRecord::Base has_many :comments, dependent: :destroy HOOKS = %i{ before_validation after_validation before_save before_create around_create after_create before_update around_update after_update after_save before_destroy around_destroy after_destroy } HOOKS.each { |h|send(h, h) } protected HOOKS.each do |sym| define_method sym do logger.info sym end end end
試行 その1 save
rails console(pry)で試行します。
[1] pry(main)> a = Article.new => #<Article id: nil, title: nil, text: nil, created_at: nil, updated_at: nil> [2] pry(main)> a.title = 'save' => "save" [3] pry(main)> a.save (0.1ms) begin transaction :before_validation :after_validation :before_save :before_create :around_create :after_create :after_save (0.1ms) commit transaction => true
試行 その2 create
rails console(pry)で試行します。
[1] pry(main)> a = Article.create(title: 'some title103', text: 'some text') (0.1ms) begin transaction :before_validation :after_validation :before_save :before_create :around_create :after_create :after_save (0.1ms) commit transaction => #<Article id: nil, title: "some title103", text: "some text", created_at: "2014-07-03 23:10:53", updated_at: "2014-07-03 23:10:53">
試行 その3 update
rails console(pry)で試行します。
[1] pry(main)> a = Article.find 1 Article Load (0.6ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = 1 LIMIT 1 => #<Article id: 1, title: "some title1", text: "some Text1", created_at: "2014-06-27 22:56:03", updated_at: "2014-06-27 23:39:55"> [2] pry(main)> a.update(title: 'changed title') (0.2ms) begin transaction :before_validation :after_validation :before_save :before_update :around_update :after_update :after_save (0.2ms) commit transaction => true
試行 その4 destroy
rails console(pry)で試行します。
[1] pry(main)> a26 = Article.find_by id:26 Article Load (1.1ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = 26 LIMIT 1 => #<Article id: 26, title: "some title101", text: "some text", created_at: "2014-07-03 23:59:45", updated_at: "2014-07-03 23:59:45"> [2] pry(main)> a26.destroy (0.1ms) begin transaction Comment Load (1.6ms) SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = ? [["article_id", 26]] :before_destroy :around_destroy :after_destroy (0.1ms) rollback transact