mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
validation macros can now be used within an instance
This commit is contained in:
parent
2203c781a7
commit
9131a88bb8
13 changed files with 114 additions and 14 deletions
|
@ -46,6 +46,9 @@ module ActiveModel
|
|||
|
||||
included do
|
||||
extend ActiveModel::Translation
|
||||
|
||||
extend HelperMethods; include HelperMethods
|
||||
|
||||
define_callbacks :validate, :scope => :name
|
||||
|
||||
attr_accessor :validation_context
|
||||
|
@ -138,12 +141,6 @@ module ActiveModel
|
|||
def attribute_method?(attribute)
|
||||
method_defined?(attribute)
|
||||
end
|
||||
private
|
||||
|
||||
def _merge_attributes(attr_names)
|
||||
options = attr_names.extract_options!
|
||||
options.merge(:attributes => attr_names.flatten)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the Errors object that holds all information about attribute error messages.
|
||||
|
|
|
@ -21,7 +21,7 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
module HelperMethods
|
||||
# Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:
|
||||
#
|
||||
# class Person < ActiveRecord::Base
|
||||
|
|
|
@ -12,7 +12,7 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
module HelperMethods
|
||||
# Encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example:
|
||||
#
|
||||
# Model:
|
||||
|
|
|
@ -12,7 +12,7 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
module HelperMethods
|
||||
# Validates that the value of the specified attribute is not in a particular enumerable object.
|
||||
#
|
||||
# class Person < ActiveRecord::Base
|
||||
|
|
|
@ -24,7 +24,7 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
module HelperMethods
|
||||
# Validates whether the value of the specified attribute is of the correct form, going by the regular expression provided.
|
||||
# You can require that the attribute matches the regular expression:
|
||||
#
|
||||
|
|
12
activemodel/lib/active_model/validations/helper_methods.rb
Normal file
12
activemodel/lib/active_model/validations/helper_methods.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
module ActiveModel
|
||||
module Validations
|
||||
module HelperMethods
|
||||
private
|
||||
|
||||
def _merge_attributes(attr_names)
|
||||
options = attr_names.extract_options!
|
||||
options.merge(:attributes => attr_names.flatten)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,7 +12,7 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
module HelperMethods
|
||||
# Validates whether the value of the specified attribute is available in a particular enumerable object.
|
||||
#
|
||||
# class Person < ActiveRecord::Base
|
||||
|
|
|
@ -51,7 +51,7 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
module HelperMethods
|
||||
|
||||
# Validates that the specified attribute matches the length restrictions supplied. Only one option can be used at a time:
|
||||
#
|
||||
|
|
|
@ -70,7 +70,7 @@ module ActiveModel
|
|||
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
module HelperMethods
|
||||
# Validates whether the value of the specified attribute is numeric by trying to convert it to
|
||||
# a float with Kernel.Float (if <tt>only_integer</tt> is false) or applying it to the regular expression
|
||||
# <tt>/\A[\+\-]?\d+\Z/</tt> (if <tt>only_integer</tt> is set to true).
|
||||
|
|
|
@ -8,7 +8,7 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
module HelperMethods
|
||||
# Validates that the specified attributes are not blank (as defined by Object#blank?). Happens by default on save. Example:
|
||||
#
|
||||
# class Person < ActiveRecord::Base
|
||||
|
|
|
@ -75,5 +75,71 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 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 :instance_validations
|
||||
#
|
||||
# def instance_validations
|
||||
# validates_with MyValidator
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# class MyValidator < ActiveModel::Validator
|
||||
# def validate(record)
|
||||
# if some_complex_logic
|
||||
# record.errors[: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 :instance_validations, :on => :create
|
||||
#
|
||||
# def instance_validations
|
||||
# validates_with MyValidator, MyOtherValidator
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Standard configuration options (:on, :if and :unless), which are
|
||||
# available on the class version of validates_with, should instead be
|
||||
# placed on the <tt>validates</tt> method as these are applied and tested
|
||||
# in the callback
|
||||
#
|
||||
# If you pass any additional configuration options, they will be passed
|
||||
# to the class and available as <tt>options</tt>:
|
||||
#
|
||||
# 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
|
||||
#
|
||||
def validates_with(*args, &block)
|
||||
options = args.extract_options!
|
||||
args.each do |klass|
|
||||
validator = klass.new(options, &block)
|
||||
validator.setup(self) if validator.respond_to?(:setup)
|
||||
validator.validate(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,6 +4,7 @@ require 'cases/helper'
|
|||
require 'models/topic'
|
||||
require 'models/reply'
|
||||
require 'models/custom_reader'
|
||||
require 'models/automobile'
|
||||
|
||||
class ValidationsTest < ActiveModel::TestCase
|
||||
|
||||
|
@ -252,4 +253,16 @@ class ValidationsTest < ActiveModel::TestCase
|
|||
Topic.validates_length_of :title, :minimum => 10
|
||||
assert_equal 10, Topic.validators_on(:title).first.options[:minimum]
|
||||
end
|
||||
|
||||
def test_validations_on_the_instance_level
|
||||
auto = Automobile.new
|
||||
|
||||
assert auto.invalid?
|
||||
assert_equal 2, auto.errors.size
|
||||
|
||||
auto.make = 'Toyota'
|
||||
auto.model = 'Corolla'
|
||||
|
||||
assert auto.valid?
|
||||
end
|
||||
end
|
||||
|
|
12
activemodel/test/models/automobile.rb
Normal file
12
activemodel/test/models/automobile.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
class Automobile
|
||||
include ActiveModel::Validations
|
||||
|
||||
validate :validations
|
||||
|
||||
attr_accessor :make, :model
|
||||
|
||||
def validations
|
||||
validates_presence_of :make
|
||||
validates_length_of :model, :within => 2..10
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue