環境
- 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 : 実行前にリクエストの検証
挙動
- 基本的な挙動
- モデルに検証する条件を定義
- 保存前に検証される
- 検証でエラーが無ければ保存、エラーがあればエラーメッセージ表示
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
参考
- http://railsdoc.com/validation
- http://www.techscore.com/blog/2012/12/25/rails%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%81%BE%E3%81%A8%E3%82%81/
- http://d.akiroom.com/2013-05/rails-activerecord-no-callback-update/
- http://gendosu.ddo.jp/redmine/projects/1/wiki/Active_record%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89
- http://maeshima.hateblo.jp/entry/20110329/1301428776