@@ -69,6 +69,11 @@ module ClassMethods
69
69
# or an array of symbols. (e.g. <tt>on: :create</tt> or
70
70
# <tt>on: :custom_validation_context</tt> or
71
71
# <tt>on: [:create, :custom_validation_context]</tt>)
72
+ # * <tt>:except_on</tt> - Specifies the contexts where this validation is not active.
73
+ # Runs in all validation contexts by default +nil+. You can pass a symbol
74
+ # or an array of symbols. (e.g. <tt>except: :create</tt> or
75
+ # <tt>except_on: :custom_validation_context</tt> or
76
+ # <tt>except_on: [:create, :custom_validation_context]</tt>)
72
77
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
73
78
# * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
74
79
# * <tt>:if</tt> - Specifies a method, proc, or string to call to determine
@@ -84,7 +89,7 @@ def validates_each(*attr_names, &block)
84
89
validates_with BlockValidator , _merge_attributes ( attr_names ) , &block
85
90
end
86
91
87
- VALID_OPTIONS_FOR_VALIDATE = [ :on , :if , :unless , :prepend ] . freeze # :nodoc:
92
+ VALID_OPTIONS_FOR_VALIDATE = [ :on , :if , :unless , :prepend , :except_on ] . freeze # :nodoc:
88
93
89
94
# Adds a validation method or block to the class. This is useful when
90
95
# overriding the +validate+ instance method becomes too unwieldy and
@@ -135,7 +140,12 @@ def validates_each(*attr_names, &block)
135
140
# or an array of symbols. (e.g. <tt>on: :create</tt> or
136
141
# <tt>on: :custom_validation_context</tt> or
137
142
# <tt>on: [:create, :custom_validation_context]</tt>)
138
- # * <tt>:if</tt> - Specifies a method, proc, or string to call to determine
143
+ # * <tt>:except_on</tt> - Specifies the contexts where this validation is not active.
144
+ # Runs in all validation contexts by default +nil+. You can pass a symbol
145
+ # or an array of symbols. (e.g. <tt>except: :create</tt> or
146
+ # <tt>except_on: :custom_validation_context</tt> or
147
+ # <tt>except_on: [:create, :custom_validation_context]</tt>)
148
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
139
149
# if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
140
150
# or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
141
151
# proc or string should return or evaluate to a +true+ or +false+ value.
@@ -162,6 +172,15 @@ def validate(*args, &block)
162
172
options = options . merge ( if : [ predicate_for_validation_context ( options [ :on ] ) , *options [ :if ] ] )
163
173
end
164
174
175
+ if options . key? ( :except_on )
176
+ options = options . dup
177
+ options [ :except_on ] = Array ( options [ :except_on ] )
178
+ options [ :unless ] = [
179
+ -> ( o ) { ( options [ :except_on ] & Array ( o . validation_context ) ) . any? } ,
180
+ *options [ :unless ]
181
+ ]
182
+ end
183
+
165
184
set_callback ( :validate , *args , options , &block )
166
185
end
167
186
0 commit comments