aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel
diff options
context:
space:
mode:
Diffstat (limited to 'activemodel')
-rw-r--r--activemodel/CHANGELOG.md6
-rw-r--r--activemodel/lib/active_model/validations.rb6
-rw-r--r--activemodel/test/cases/validations_test.rb6
3 files changed, 18 insertions, 0 deletions
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 555cd259d2..c8ee8ad7de 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Validate options passed to `ActiveModel::Validations::validate`
+
+ Preventing, in many cases, the simple mistake of using `validate` instead of `validate`.
+
+ *Sonny Michaud*
+
* Deprecate `reset_#{attribute}` in favor of `restore_#{attribute}`.
These methods may cause confusion with the `reset_changes` that behaves differently
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index cf97f45dba..b3d345c8ca 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -141,6 +141,11 @@ module ActiveModel
# value.
def validate(*args, &block)
options = args.extract_options!
+
+ if args.all? { |arg| arg.is_a?(Symbol) }
+ options.assert_valid_keys(%i(on if unless))
+ end
+
if options.key?(:on)
options = options.dup
options[:if] = Array(options[:if])
@@ -148,6 +153,7 @@ module ActiveModel
Array(options[:on]).include?(o.validation_context)
}
end
+
args << options
set_callback(:validate, *args, &block)
end
diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb
index 4fee704ef5..948efd0f0a 100644
--- a/activemodel/test/cases/validations_test.rb
+++ b/activemodel/test/cases/validations_test.rb
@@ -167,6 +167,12 @@ class ValidationsTest < ActiveModel::TestCase
end
end
+ def test_invalid_options_to_validate
+ assert_raises(ArgumentError) do
+ Topic.validate :title, presence: true
+ end
+ end
+
def test_errors_conversions
Topic.validates_presence_of %w(title content)
t = Topic.new