6
6

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.

validate, callbackとacts_as_paranoidを組み合わせたときの挙動

Last updated at Posted at 2013-05-23

環境

  • ruby : 1.9.3p392
  • rails : 3.2.13
  • sqlite3 : 3.7.9
  • rails3_acts_as_paranoid : 0.2.5
  • この記事では、以下のモデルを使用する
class User < ActiveRecord::Base
  acts_as_paranoid
  attr_accessible :email, :name, :tel

  validates :name, presence: true, uniqueness: true

  private

  def return_false
    false
  end

  def add_error
    errors.add(:base, 'added error')
  end

  def raise_error
    raise StandardError
  end
end

一覧

validateでの指定 専用メソッド 内容
presence validates_presence_of 値が空でないか
uniqueness validates_uniqueness_of 一意性
acceptance validates_acceptance_of チェックボックスにチェックが入っているか
confirmation validates_confirmation_of 2つのフィールドが等しいか
exclusion validates_exclusion_of 値が配列・範囲に含まれていないか
format validates_format_of 正規表現に一致するか検証
inclusion validates_inclusion_of 値が配列・範囲に含まれるか
length validates_length_of 文字列の長さ
numericality validates_numericality_of 数値の大小、型
--- validates_absence_of 空白か
--- validates_associated 関連先の検証
  • その他
  • validate : モデルの検証を定義する
  • verify : 実行前にリクエストの検証

挙動

  • 基本的な挙動
  1. モデルに検証する条件を定義
  2. 保存前に検証される
  3. 検証でエラーが無ければ保存、エラーがあればエラーメッセージ表示

before_validationとafter_validation

  • before_validation
  • falseを返すと、validateは実行されずロールバックされる
# before_validation :return_false
# after_validation  :raise_error
User.create(name: "val")  #=> rollback
  • after_validation
  • falseを返しても、validateがtrueならロールバックされない
  • errors.add を実行してもtrueが返る
# after_validation  :return_false
User.create(name: "aaaa")  #=> save
# after_validation  :add_error
User.create(name: "bbbb")  #=> false

実行順

  • valid?
  • before_validation
  • before_validation :on => {:create, :update}
  • validate
  • validate :on => {:create, :update}
  • after_validation
  • after_validation :on => {:create, :update}

callbackの無効化と有効化

  • skip_callback, set_callbackを使う
  • callbackの登録に使われているメソッド
# Disable
#   before_create :raise_error
User.skip_callback(:create, :before, :raise_error)
user = User.new
user.name = "hoge"
user.save                  #=> true
User.create(name: "fuga")  #=> true

# Enable
User.set_callback(:create, :before, :raise_error)
user = User.new
user.name = "piyo"
user.save                  #=> StandardError
User.create(name: "fuga")  #=> StandardError

acts_as_paranoidとの組み合わせ

  • acts_as_paranoidはdestroyを書き換え, recoverやdestroy!を追加する
  • recover用のcallbackとしてbefore_recover, after_recoverが追加される
  • どのcallbackを定義したら効くか

結論

  • acts_as_paranoidの書き換えは気にしなくてもいい
  • destroy, destroy!ともにxxx_destroyのcallbackだけ効く
  • recoverにはxxx_updateのcallbackが効く

before_create, after_create, around_create

  • destroy, recoverには無関係
# after_create :raise_error
User.only_deleted.last.recover  #=> true

before_update, after_update, around_update

  • recoverに有効
# around_update :raise_error
User.last.destroy                                    #=> true
User.last.destroy!                                   #=> true
User.only_deleted.last.destroy                       #=> true
User.destroy_all                                     #=> true
User.delete(1)                                       #=> true
User.delete_all                                      #=> true
User.last.update_attribute(:deleted_at, Time.now)    #=> StandardError
User.only_deleted.update_attribute(:deleted_at, nil) #=> StandardError
User.only_deleted.last.recover                       #=> StandardError

before_destroy, after_destroy, around_destroy

  • destroy, destroy!, destroy_allに有効
# around_destroy :raise_error
User.last.destroy                                 #=> StandardError
User.last.destroy!                                #=> StandardError
User.only_deleted.last.destroy                    #=> StandardError
User.destroy_all                                  #=> StandardError
User.delete(1)                                    #=> true
User.delete_all                                   #=> true
User.last.update_attribute(:deleted_at, Time.now) #=> true

参考

6
6
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
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?