Skip to content

Commit 50d9717

Browse files
Merge pull request rails#13754 from vpuzzella/master
Ability to specify multiple contexts when defining a validation.
2 parents 3fd6329 + 8855163 commit 50d9717

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

activemodel/CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
* Ability to specify multiple contexts when defining a validation.
2+
3+
Example:
4+
5+
class Person
6+
include ActiveModel::Validations
7+
8+
attr_reader :name
9+
validates_presence_of :name, on: [:verify, :approve]
10+
end
11+
12+
person = Person.new
13+
person.valid? # => true
14+
person.valid?(:verify) # => false
15+
person.errors.full_messages_for(:name) # => ["Name can't be blank"]
16+
person.valid?(:approve) # => false
17+
person.errors.full_messages_for(:name) # => ["Name can't be blank"]
18+
19+
*Vince Puzzella*
20+
121
* `attribute_changed?` now accepts parameters which check the old and new value of the attribute
222

323
`model.name_changed?(from: "Pete", to: "Ringo")`

activemodel/lib/active_model/validations.rb

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ module ClassMethods
6666
# end
6767
#
6868
# Options:
69-
# * <tt>:on</tt> - Specifies the context where this validation is active
70-
# (e.g. <tt>on: :create</tt> or <tt>on: :custom_validation_context</tt>)
69+
# * <tt>:on</tt> - Specifies the contexts where this validation is active.
70+
# You can pass a symbol or an array of symbols.
71+
# (e.g. <tt>on: :create</tt> or <tt>on: :custom_validation_context</tt> or
72+
# <tt>on: [:create, :custom_validation_context]</tt>)
7173
# * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
7274
# * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
7375
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
@@ -124,8 +126,10 @@ def validates_each(*attr_names, &block)
124126
# end
125127
#
126128
# Options:
127-
# * <tt>:on</tt> - Specifies the context where this validation is active
128-
# (e.g. <tt>on: :create</tt> or <tt>on: :custom_validation_context</tt>)
129+
# * <tt>:on</tt> - Specifies the contexts where this validation is active.
130+
# You can pass a symbol or an array of symbols.
131+
# (e.g. <tt>on: :create</tt> or <tt>on: :custom_validation_context</tt> or
132+
# <tt>on: [:create, :custom_validation_context]</tt>)
129133
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine
130134
# if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
131135
# or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
@@ -141,7 +145,7 @@ def validate(*args, &block)
141145
options = options.dup
142146
options[:if] = Array(options[:if])
143147
options[:if].unshift lambda { |o|
144-
o.validation_context == options[:on]
148+
Array(options[:on]).include?(o.validation_context)
145149
}
146150
end
147151
args << options

activemodel/test/cases/validations/validations_context_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,20 @@ def validate(record)
3636
assert topic.invalid?(:create), "Validation does run on create if 'on' is set to create"
3737
assert topic.errors[:base].include?(ERROR_MESSAGE)
3838
end
39+
40+
test "with a class that adds errors on multiple contexts and validating a new model with no arguments" do
41+
Topic.validates_with(ValidatorThatAddsErrors, on: [:context1, :context2])
42+
topic = Topic.new
43+
assert topic.valid?, "Validation doesn't run when 'on' is set to context1 and context2"
44+
end
45+
46+
test "with a class that adds errors on multiple contexts and validating a new model" do
47+
Topic.validates_with(ValidatorThatAddsErrors, on: [:context1, :context2])
48+
topic = Topic.new
49+
assert topic.invalid?(:context1), "Validation does run on context1 when 'on' is set to context1 and context2"
50+
assert topic.errors[:base].include?(ERROR_MESSAGE)
51+
topic = Topic.new
52+
assert topic.invalid?(:context2), "Validation does run on context2 when 'on' is set to context1 and context2"
53+
assert topic.errors[:base].include?(ERROR_MESSAGE)
54+
end
3955
end

0 commit comments

Comments
 (0)