LoginSignup
0
0

More than 5 years have passed since last update.

validates_xxx_ofとvalidatesとvalidates_withとvalidateの関係が分からかったので追ってみた

Last updated at Posted at 2016-07-18

結論

何れもvalidateの呼び出しに還元され、set_callbackで登録される。

準備

app/models/user.rb
class User < ActiveRecord::Base
  validates :name, my: {hoge: :fuga}, if: :name_present?

  private
    def name_present?
      true
    end
end
app/validators/my_validator.rb
class MyValidator < ActiveModel::Validator
  def initialize(options)
    Rails.logger.debug 'in MyValidator#options'
    Rails.logger.debug options
  end

  def validate(user)
  end

  private
end

呼び出し関係

/active_model/validations/validates.rb
module ActiveModel
  module Validations
    module ClassMethods
      ...
      def validates(*attributes)
      ...
        # validates_withが次の形で呼ばれる
        # シンボル :my から MyValidator クラスへ変換される事に注意
        # 
        #   validates_with(
        #     MyValidator,
        #     {:if=>:name_present?, :attributes=>[:name], :hoge=>:fuga}
        #   )
active_model/validations/with.rb
module ActiveModel
  module Validations
    module ClassMethods
      ...
      def validates_with(*args, &block)
        ...
        # validateが次の形で呼ばれる
        # 
        #   validate(
        #     #<MyValidator:0x007fb1535f2c40>,
        #     {:if=>:name_present?, :hoge=>:fuga, :class=>User}
        #   )
        #   
        # MyValidatorはインスタンスで呼ばれる事に注意
        #   newの引数にオプションとブロックが渡される。バリデータのinitializeで利用できる
        #     klass.new(options, &block)
        # 
        # アトリビュート指定はどこへ行った?
        #  メソッドの途中で _validators[attribute.to_sym] << validator
/active_model/validations.rb
module ActiveModel
  module Validations
    module ClassMethods
      ...
      def validate(*args, &block)
         ...
         # set_callbackが次の形で呼ばれる
         #
         #   set_callback(
         #    [
         #      #<MyValidator:0x007fb1535f2c40>, 
         #      {:if=>:name_present?, :attributes=>[:name], :hoge=>:fuga, :class=>User}
         #    ]

validates_xxx_of は 単にvalidates_withへのラッパー

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