railsが提供するvalidators

42922 ワード

Instance Public methods
attribute_method?(attribute)

Returns  true  if  attribute  is an attribute method,  false  otherwise.
class Person

  include ActiveModel::Validations



  attr_accessor :name

end



User.attribute_method?(:name) # => true

User.attribute_method?(:age)  # => false


Source: show |  on GitHub
clear_validators!()

Clears all of the validators and validations.
Note that this will clear anything that is being used to validate the model for both the  validates_with  and  validate  methods. It clears the validators that are created with an invocation of  validates_with  and the callbacks that are set by an invocation of  validate .
class Person

  include ActiveModel::Validations



  validates_with MyValidator

  validates_with OtherValidator, on: :create

  validates_with StrictValidator, strict: true

  validate :cannot_be_robot



  def cannot_be_robot

    errors.add(:base, 'A person cannot be a robot') if person_is_robot

  end

end



Person.validators

# => [

#      #<MyValidator:0x007fbff403e808 @options={}>,

#      #<OtherValidator:0x007fbff403d930 @options={on: :create}>,

#      #<StrictValidator:0x007fbff3204a30 @options={strict:true}>

#    ]


If one runs Person.clear_validators! and then checks to see what validators this class has, you would obtain:
Person.validators # => []


Also, the callback set by +validate :cannot_be_robot+ will be erased so that:
Person._validate_callbacks.empty?  # => true


Source: show |  on GitHub
validate(*args, &block)

Adds a validation method or block to the class. This is useful when overriding the  validate  instance method becomes too unwieldy and you’re looking for more descriptive declaration of your validations.
This can be done with a symbol pointing to a method:
class Comment

  include ActiveModel::Validations



  validate :must_be_friends



  def must_be_friends

    errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)

  end

end


With a block which is passed with the current record to be validated:
class Comment

  include ActiveModel::Validations



  validate do |comment|

    comment.must_be_friends

  end



  def must_be_friends

    errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)

  end

end


Or with a block where self points to the current record to be validated:
class Comment

  include ActiveModel::Validations



  validate do

    errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)

  end

end


Options:
  • :on  - Specifies the context where this validation is active (e.g.  on: :create  or  on: :custom_validation_context )
  • :allow_nil  - Skip validation if attribute is  nil .
  • :allow_blank  - Skip validation if attribute is blank.
  • :if  - Specifies a method, proc or string to call to determine if the validation should occur (e.g.  if: :allow_validation , or  if: Proc.new { |user| user.signup_step > 2 } ). The method, proc or string should return or evaluate to a true  or  false  value.
  • :unless  - Specifies a method, proc or string to call to determine if the validation should not occur (e.g.  unless: :skip_validation , or  unless: Proc.new { |user| user.signup_step <= 2 } ). The method, proc or string should return or evaluate to a  true  or  false  value.

  • Source: show |  on GitHub
    validates(*attributes)

    This method is a shortcut to all default validators and any custom validator classes ending in ‘Validator’. Note that  Rails  default validators can be overridden inside specific classes by creating custom validator classes in their place such as PresenceValidator.
    Examples of using the default rails validators:
    validates :terms, acceptance: true
    
    validates :password, confirmation: true
    
    validates :username, exclusion: { in: %w(admin superuser) }
    
    validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, on: :create }
    
    validates :age, inclusion: { in: 0..9 }
    
    validates :first_name, length: { maximum: 30 }
    
    validates :age, numericality: true
    
    validates :username, presence: true
    
    validates :username, uniqueness: true

    The power of the  validates  method comes when using custom validators and default validators in one call for a given attribute.
    class EmailValidator < ActiveModel::EachValidator
    
      def validate_each(record, attribute, value)
    
        record.errors.add attribute, (options[:message] || "is not an email") unless
    
          value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/
    
      end
    
    end
    
    
    
    class Person
    
      include ActiveModel::Validations
    
      attr_accessor :name, :email
    
    
    
      validates :name, presence: true, uniqueness: true, length: { maximum: 100 }
    
      validates :email, presence: true, email: true
    
    end
    
    

    Validator  classes may also exist within the class being validated allowing custom modules of validators to be included as needed.
    class Film
    
      include ActiveModel::Validations
    
    
    
      class TitleValidator < ActiveModel::EachValidator
    
        def validate_each(record, attribute, value)
    
          record.errors.add attribute, "must start with 'the'" unless value =~ /\Athe/
    
        end
    
      end
    
    
    
      validates :name, title: true
    
    end
    
    

    Additionally validator classes may be in another namespace and still used within any class.
    validates :name, :'film/title' => true
    
    

    The validators hash can also handle regular expressions, ranges, arrays and strings in shortcut form.
    validates :email, format: /@/
    
    validates :gender, inclusion: %w(male female)
    
    validates :password, length: 6..20

    When using shortcut form, ranges and arrays are passed to your validator’s initializer as  options[:in]  while other types including regular expressions and strings are passed as  options[:with] .
    There is also a list of options that could be used along with validators:
  • :on  - Specifies when this validation is active. Runs in all validation contexts by default ( nil ), other options are  :create  and  :update .
  • :if  - Specifies a method, proc or string to call to determine if the validation should occur (e.g.  if: :allow_validation , or  if: Proc.new { |user| user.signup_step > 2 } ). The method, proc or string should return or evaluate to a true  or  false  value.
  • :unless  - Specifies a method, proc or string to call to determine if the validation should not occur (e.g.  unless: :skip_validation , or  unless: Proc.new { |user| user.signup_step <= 2 } ). The method, proc or string should return or evaluate to a  true  or  false  value.
  • :strict  - if the  :strict  option is set to true will raise  ActiveModel::StrictValidationFailed  instead of adding the error.  :strict  option can also be set to any other exception.

  • Example:
    validates :password, presence: true, confirmation: true, if: :password_required?
    
    validates :token, uniqueness: true, strict: TokenGenerationException

    Finally, the options  :if:unless:on:allow_blank:allow_nil:strict  and  :message  can be given to one specific validator, as a hash:
    validates :password, presence: { if: :password_required?, message: 'is forgotten.' }, confirmation: true

    Source: show |  on GitHub
    validates!(*attributes)

    This method is used to define validations that cannot be corrected by end users and are considered exceptional. So each validator defined with bang or  :strict  option set to  true  will always raise ActiveModel::StrictValidationFailed  instead of adding error when validation fails. See  validates  for more information about the validation itself.
    class Person
    
      include ActiveModel::Validations
    
    
    
      attr_accessor :name
    
      validates! :name, presence: true
    
    end
    
    
    
    person = Person.new
    
    person.name = ''
    
    person.valid?
    
    # => ActiveModel::StrictValidationFailed: Name can't be blank
    
    

    Source: show |  on GitHub
    validates_each(*attr_names, &block)

    Validates each attribute against a block.
    class Person
    
      include ActiveModel::Validations
    
    
    
      attr_accessor :first_name, :last_name
    
    
    
      validates_each :first_name, :last_name, allow_blank: true do |record, attr, value|
    
        record.errors.add attr, 'starts with z.' if value.to_s[0] == z
    
      end
    
    end
    
    

    Options:
  • :on  - Specifies the context where this validation is active (e.g.  on: :create  or  on: :custom_validation_context )
  • :allow_nil  - Skip validation if attribute is  nil .
  • :allow_blank  - Skip validation if attribute is blank.
  • :if  - Specifies a method, proc or string to call to determine if the validation should occur (e.g.  if: :allow_validation , or  if: Proc.new { |user| user.signup_step > 2 } ). The method, proc or string should return or evaluate to a true  or  false  value.
  • :unless  - Specifies a method, proc or string to call to determine if the validation should not occur (e.g.  unless: :skip_validation , or  unless: Proc.new { |user| user.signup_step <= 2 } ). The method, proc or string should return or evaluate to a  true  or  false  value.

  • Source: show |  on GitHub
    validates_with(*args, &block)

    Passes the record off to the class or classes specified and allows them to add errors based on more complex conditions.
    class Person
    
      include ActiveModel::Validations
    
      validates_with MyValidator
    
    end
    
    
    
    class MyValidator < ActiveModel::Validator
    
      def validate(record)
    
        if some_complex_logic
    
          record.errors.add :base, 'This record is invalid'
    
        end
    
      end
    
    
    
      private
    
        def some_complex_logic
    
          # ...
    
        end
    
    end
    
    

    You may also pass it multiple classes, like so:
    class Person
    
      include ActiveModel::Validations
    
      validates_with MyValidator, MyOtherValidator, on: :create
    
    end
    
    

    Configuration options:
  • :on  - Specifies when this validation is active ( :create  or  :update .
  • :if  - Specifies a method, proc or string to call to determine if the validation should occur (e.g.  if: :allow_validation , or  if: Proc.new { |user| user.signup_step > 2 } ). The method, proc or string should return or evaluate to a true  or  false  value.
  • :unless  - Specifies a method, proc or string to call to determine if the validation should not occur (e.g.  unless: :skip_validation , or  unless: Proc.new { |user| user.signup_step <= 2 } ). The method, proc or string should return or evaluate to a  true  or  false  value.
  • :strict  - Specifies whether validation should be strict. See  ActiveModel::Validation#validates!  for more information.

  • If you pass any additional configuration options, they will be passed to the class and available as  options :
    class Person
    
      include ActiveModel::Validations
    
      validates_with MyValidator, my_custom_key: 'my custom value'
    
    end
    
    
    
    class MyValidator < ActiveModel::Validator
    
      def validate(record)
    
        options[:my_custom_key] # => "my custom value"
    
      end
    
    end
    
    

    Source: show |  on GitHub
    validators()

    List all validators that are being used to validate the model using  validates_with  method.
    class Person
    
      include ActiveModel::Validations
    
    
    
      validates_with MyValidator
    
      validates_with OtherValidator, on: :create
    
      validates_with StrictValidator, strict: true
    
    end
    
    
    
    Person.validators
    
    # => [
    
    #      #<MyValidator:0x007fbff403e808 @options={}>,
    
    #      #<OtherValidator:0x007fbff403d930 @options={on: :create}>,
    
    #      #<StrictValidator:0x007fbff3204a30 @options={strict:true}>
    
    #    ]
    
    

    Source: show |  on GitHub
    validators_on(*attributes)

    List all validators that are being used to validate a specific attribute.
    class Person
    
      include ActiveModel::Validations
    
    
    
      attr_accessor :name , :age
    
    
    
      validates_presence_of :name
    
      validates_inclusion_of :age, in: 0..99
    
    end
    
    
    
    Person.validators_on(:name)
    
    # => [
    
    #       #<ActiveModel::Validations::PresenceValidator:0x007fe604914e60 @attributes=[:name], @options={}>,
    
    #       #<ActiveModel::Validations::InclusionValidator:0x007fe603bb8780 @attributes=[:age], @options={in:0..99}>
    
    #    ]