0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

コールバックの続き

コールバックの実行となるトリガ

データベースに影響を与える処理 と  保存時じゃなくてもトリガとなる valid?

  • create
  • create!
  • destroy
  • destroy!
  • destroy_all
  • save
  • save!
  • save(validate: false) • toggle!
  • touch
  • update_attribute
  • update
  • update!
  • valid?

データベースから、レコードを読み込むたびに呼び出される after_find では、下記がトリガとなる

  • all
  • first
  • find
  • find_by
  • find_by_*
  • find_by_*!
  • find_by_sql
  • last

関連モデルのコールバック

親子関係のモデル経由でコールバックを実行することができる

user.rb
class User < ApplicationRecord
has_many :posts , dependent: :destroy

end
post.rb
class Post < ApplicationRecord

  def log_destroy_action
    puts 'Userが消えたよ!'
  end
end

>> user = User.first
=> #<User id: 1>
>> user.posts.create!
=> #<Post id: 1, user_id: 1>
>> user.destroy
Userが消えたよ
=> #<User id: 1>

:if や :unlessでオプションをつけられる

バリデーションでよく使う

user.rb
class User < ApplicationRecord
  before_save :user_search, if: :user_exists?
end

コールバックclassを作れる

Active Recordはコールバックメソッドをカプセル化したクラスを作成できる(Railsガイドより引用)

class PictureFileCallbacks
  def after_destroy(picture_file)
    if File.exist?(picture_file.filepath) File.delete(picture_file.filepath)
      File.delete(picture_file.filepath)
    end
  end
end

クラス内で宣言することにより、コールバックメソッドはモデルオブジェクトをパラメーターとして受け取れるようになる
=> これでモデル内で使用可能

class PictureFile < ApplicationRecord after_destroy PictureFileCallbacks.new
  after_destroy PictureFileCallbacks.new
end

コールバックをインスタンスメソッドとして宣言したため、 PictureFileCallbacks オブジェクト を新しくインスタンス化する必要があった
コールバックをクラスメソッドとして宣言する方がいいパターンも...

class PictureFileCallbacks
  def self.after_destroy(picture_file)
    if File.exist?(picture_file.filepath) File.delete(picture_file.filepath)
      File.delete(picture_file.filepath)
    end
  end
end

クラスメソッドなら、インスタンス化は不要ですね♪

トランザクションコールバック

データベースのトランザクションが完了したときにトリガされるコールバック
Active Record のモデルから、データベーストランザクションの一部に含まれていない外部のシステムとやりとりを行ないたい場合に使用する

  • after_commit
  • after_rollback

※ データベースの変更のcommit、rollbackが完了するまでトリガされない

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?