Skip to content
Newer
Older
100644 170 lines (159 sloc) 6.85 KB
afd0c06 @josevalim Validates needs hash slice.
josevalim authored
1 require 'active_support/core_ext/hash/slice'
2
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
3 module ActiveModel
4 module Validations
5 module ClassMethods
6 # This method is a shortcut to all default validators and any custom
7 # validator classes ending in 'Validator'. Note that Rails default
8 # validators can be overridden inside specific classes by creating
9 # custom validator classes in their place such as PresenceValidator.
b95d6e8 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
10 #
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
11 # Examples of using the default rails validators:
7045c4c @josevalim Allow validates to map some types to specific options. So now you can…
josevalim authored
12 #
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
13 # validates :terms, acceptance: true
14 # validates :password, confirmation: true
15 # validates :username, exclusion: { in: %w(admin superuser) }
16 # validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, on: :create }
17 # validates :age, inclusion: { in: 0..9 }
18 # validates :first_name, length: { maximum: 30 }
19 # validates :age, numericality: true
20 # validates :username, presence: true
21 # validates :username, uniqueness: true
b95d6e8 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
22 #
ccf9577 @dolzenko Fix a bunch of minor spelling mistakes
dolzenko authored
23 # The power of the +validates+ method comes when using custom validators
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
24 # and default validators in one call for a given attribute.
7045c4c @josevalim Allow validates to map some types to specific options. So now you can…
josevalim authored
25 #
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
26 # class EmailValidator < ActiveModel::EachValidator
27 # def validate_each(record, attribute, value)
c317419 @dolzenko Use .add instead of << to add errors
dolzenko authored
28 # record.errors.add attribute, (options[:message] || "is not an email") unless
ea2ad26 @fxn you rarely want ^ or $ in validations, use \A when you mean \A
fxn authored
29 # value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
30 # end
31 # end
b95d6e8 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
32 #
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
33 # class Person
34 # include ActiveModel::Validations
35 # attr_accessor :name, :email
b95d6e8 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
36 #
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
37 # validates :name, presence: true, uniqueness: true, length: { maximum: 100 }
38 # validates :email, presence: true, email: true
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
39 # end
b95d6e8 @spastorino Deletes trailing whitespaces (over text files only find * -type f -ex…
spastorino authored
40 #
fff917e @fxn fixes a typo reported by rymai
fxn authored
41 # Validator classes may also exist within the class being validated
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
42 # allowing custom modules of validators to be included as needed.
7045c4c @josevalim Allow validates to map some types to specific options. So now you can…
josevalim authored
43 #
44 # class Film
45 # include ActiveModel::Validations
46 #
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
47 # class TitleValidator < ActiveModel::EachValidator
48 # def validate_each(record, attribute, value)
c317419 @dolzenko Use .add instead of << to add errors
dolzenko authored
49 # record.errors.add attribute, "must start with 'the'" unless value =~ /\Athe/i
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
50 # end
51 # end
47a5fd4 @josevalim Allow :if, :unless, :on, :allow_nil and :allow_blank as shared option…
josevalim authored
52 #
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
53 # validates :name, title: true
7045c4c @josevalim Allow validates to map some types to specific options. So now you can…
josevalim authored
54 # end
55 #
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
56 # Additionally validator classes may be in another namespace and still
57 # used within any class.
972011a @samuelkadolph Add support for namespaced validators
samuelkadolph authored
58 #
fd17ffc @byroot Fix a tiny typo in custom validators documentation
byroot authored
59 # validates :name, :'film/title' => true
972011a @samuelkadolph Add support for namespaced validators
samuelkadolph authored
60 #
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
61 # The validators hash can also handle regular expressions, ranges, arrays
62 # and strings in shortcut form.
7045c4c @josevalim Allow validates to map some types to specific options. So now you can…
josevalim authored
63 #
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
64 # validates :email, format: /@/
65 # validates :gender, inclusion: %w(male female)
66 # validates :password, length: 6..20
47a5fd4 @josevalim Allow :if, :unless, :on, :allow_nil and :allow_blank as shared option…
josevalim authored
67 #
275f922 @obie Better shortcut options for custom validators [#5672 state:resolved]
obie authored
68 # When using shortcut form, ranges and arrays are passed to your
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
69 # validator's initializer as <tt>options[:in]</tt> while other types
70 # including regular expressions and strings are passed as <tt>options[:with]</tt>.
275f922 @obie Better shortcut options for custom validators [#5672 state:resolved]
obie authored
71 #
c175563 @bogdan AM::Validations: remove documentation duplicates
bogdan authored
72 # There is also a list of options that could be used along with validators:
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
73 #
c175563 @bogdan AM::Validations: remove documentation duplicates
bogdan authored
74 # * <tt>:on</tt> - Specifies when this validation is active. Runs in all
75 # validation contexts by default (+nil+), other options are <tt>:create</tt>
76 # and <tt>:update</tt>.
77 # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
78 # if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
79 # or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
80 # proc or string should return or evaluate to a +true+ or +false+ value.
81 # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine
82 # if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
83 # or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
84 # method, proc or string should return or evaluate to a +true+ or
85 # +false+ value.
2e4f798 @bogdan AM::Validation#validates: ability to pass custom exception to `:stric…
bogdan authored
86 # * <tt>:strict</tt> - if the <tt>:strict</tt> option is set to true
87 # will raise ActiveModel::StrictValidationFailed instead of adding the error.
88 # <tt>:strict</tt> option can also be set to any other exception.
c175563 @bogdan AM::Validations: remove documentation duplicates
bogdan authored
89 #
90 # Example:
91 #
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
92 # validates :password, presence: true, confirmation: true, if: :password_required?
2e4f798 @bogdan AM::Validation#validates: ability to pass custom exception to `:stric…
bogdan authored
93 # validates :token, uniqueness: true, strict: TokenGenerationException
94 #
47a5fd4 @josevalim Allow :if, :unless, :on, :allow_nil and :allow_blank as shared option…
josevalim authored
95 #
fce0d08 @makaroni4 Added forgotten :message option to ActiveModel validates documentation
makaroni4 authored
96 # Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+, +:strict+
97 # and +:message+ can be given to one specific validator, as a hash:
47a5fd4 @josevalim Allow :if, :unless, :on, :allow_nil and :allow_blank as shared option…
josevalim authored
98 #
fce0d08 @makaroni4 Added forgotten :message option to ActiveModel validates documentation
makaroni4 authored
99 # validates :password, presence: { if: :password_required?, message: 'is forgotten.' }, confirmation: true
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
100 def validates(*attributes)
e84998c @dreamfall validates method should not change options argument
dreamfall authored
101 defaults = attributes.extract_options!.dup
ed7614a @carllerche Provide a way to specify alternate option keys for validates
carllerche authored
102 validations = defaults.slice!(*_validates_default_keys)
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
103
104 raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
105 raise ArgumentError, "You need to supply at least one validation" if validations.empty?
47a5fd4 @josevalim Allow :if, :unless, :on, :allow_nil and :allow_blank as shared option…
josevalim authored
106
d9f20c5 @carlosantoniodasilva Set hash value instead of using merge!
carlosantoniodasilva authored
107 defaults[:attributes] = attributes
47a5fd4 @josevalim Allow :if, :unless, :on, :allow_nil and :allow_blank as shared option…
josevalim authored
108
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
109 validations.each do |key, options|
b3ccd7b @purcell Don't enable validations when passing false hash values to ActiveMode…
purcell authored
110 next unless options
972011a @samuelkadolph Add support for namespaced validators
samuelkadolph authored
111 key = "#{key.to_s.camelize}Validator"
112
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
113 begin
972011a @samuelkadolph Add support for namespaced validators
samuelkadolph authored
114 validator = key.include?('::') ? key.constantize : const_get(key)
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
115 rescue NameError
116 raise ArgumentError, "Unknown validator: '#{key}'"
117 end
118
7045c4c @josevalim Allow validates to map some types to specific options. So now you can…
josevalim authored
119 validates_with(validator, defaults.merge(_parse_validates_options(options)))
120 end
121 end
122
d7a85c5 @vijaydev revise docs [ci skip]
vijaydev authored
123 # This method is used to define validations that cannot be corrected by end
124 # users and are considered exceptional. So each validator defined with bang
26861e9 @carlosantoniodasilva Generate strict validation error messages with attribute name
carlosantoniodasilva authored
125 # or <tt>:strict</tt> option set to <tt>true</tt> will always raise
126 # <tt>ActiveModel::StrictValidationFailed</tt> instead of adding error
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
127 # when validation fails. See <tt>validates</tt> for more information about
128 # the validation itself.
129 #
130 # class Person
9ac095f minor edits and remove mixed titles in AM::Validations docs [ci skip]
Francesco Rodriguez authored
131 # include ActiveModel::Validations
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
132 #
133 # attr_accessor :name
134 # validates! :name, presence: true
135 # end
136 #
137 # person = Person.new
9ac095f minor edits and remove mixed titles in AM::Validations docs [ci skip]
Francesco Rodriguez authored
138 # person.name = ''
139 # person.valid?
097bfc8 update #validates and #validates! documentation [ci skip]
Francesco Rodriguez authored
140 # # => ActiveModel::StrictValidationFailed: Name can't be blank
8620bf9 @bogdan Implemented strict validation concept
bogdan authored
141 def validates!(*attributes)
142 options = attributes.extract_options!
143 options[:strict] = true
144 validates(*(attributes << options))
145 end
146
7045c4c @josevalim Allow validates to map some types to specific options. So now you can…
josevalim authored
147 protected
148
ed7614a @carllerche Provide a way to specify alternate option keys for validates
carllerche authored
149 # When creating custom validators, it might be useful to be able to specify
150 # additional default keys. This can be done by overwriting this method.
9ac095f minor edits and remove mixed titles in AM::Validations docs [ci skip]
Francesco Rodriguez authored
151 def _validates_default_keys # :nodoc:
26861e9 @carlosantoniodasilva Generate strict validation error messages with attribute name
carlosantoniodasilva authored
152 [:if, :unless, :on, :allow_blank, :allow_nil , :strict]
ed7614a @carllerche Provide a way to specify alternate option keys for validates
carllerche authored
153 end
154
9ac095f minor edits and remove mixed titles in AM::Validations docs [ci skip]
Francesco Rodriguez authored
155 def _parse_validates_options(options) # :nodoc:
7045c4c @josevalim Allow validates to map some types to specific options. So now you can…
josevalim authored
156 case options
157 when TrueClass
158 {}
159 when Hash
160 options
161 when Range, Array
162 { :in => options }
275f922 @obie Better shortcut options for custom validators [#5672 state:resolved]
obie authored
163 else
164 { :with => options }
0a79eb7 @thelucid Add validates method as shortcut to setup validators for a given set …
thelucid authored
165 end
166 end
167 end
168 end
7176ade @carllerche Do not require that validation attributes be specified as symbols
carllerche authored
169 end
Something went wrong with that request. Please try again.