aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/validations/absence.rb2
-rw-r--r--activerecord/lib/active_record/validations/length.rb2
-rw-r--r--activerecord/lib/active_record/validations/presence.rb2
-rw-r--r--activerecord/test/cases/validations/absence_validation_test.rb14
-rw-r--r--activerecord/test/cases/validations/length_validation_test.rb16
-rw-r--r--activerecord/test/cases/validations/presence_validation_test.rb15
6 files changed, 48 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/validations/absence.rb b/activerecord/lib/active_record/validations/absence.rb
index 2e19e6dc5c..376d743c92 100644
--- a/activerecord/lib/active_record/validations/absence.rb
+++ b/activerecord/lib/active_record/validations/absence.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module Validations
class AbsenceValidator < ActiveModel::Validations::AbsenceValidator # :nodoc:
def validate_each(record, attribute, association_or_value)
- return unless should_validate?(record)
+ return unless should_validate?(record) || unknown_attribute?(record, attribute)
if record.class._reflect_on_association(attribute)
association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?)
end
diff --git a/activerecord/lib/active_record/validations/length.rb b/activerecord/lib/active_record/validations/length.rb
index 69e048eef1..fe34e4875c 100644
--- a/activerecord/lib/active_record/validations/length.rb
+++ b/activerecord/lib/active_record/validations/length.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module Validations
class LengthValidator < ActiveModel::Validations::LengthValidator # :nodoc:
def validate_each(record, attribute, association_or_value)
- return unless should_validate?(record) || associations_are_dirty?(record)
+ return unless should_validate?(record) || unknown_attribute?(record, attribute) || associations_are_dirty?(record)
if association_or_value.respond_to?(:loaded?) && association_or_value.loaded?
association_or_value = association_or_value.target.reject(&:marked_for_destruction?)
end
diff --git a/activerecord/lib/active_record/validations/presence.rb b/activerecord/lib/active_record/validations/presence.rb
index 7e85ed43ac..e34d2d70ab 100644
--- a/activerecord/lib/active_record/validations/presence.rb
+++ b/activerecord/lib/active_record/validations/presence.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module Validations
class PresenceValidator < ActiveModel::Validations::PresenceValidator # :nodoc:
def validate_each(record, attribute, association_or_value)
- return unless should_validate?(record)
+ return unless should_validate?(record) || unknown_attribute?(record, attribute)
if record.class._reflect_on_association(attribute)
association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?)
end
diff --git a/activerecord/test/cases/validations/absence_validation_test.rb b/activerecord/test/cases/validations/absence_validation_test.rb
index dd43ee358c..180acbcb6a 100644
--- a/activerecord/test/cases/validations/absence_validation_test.rb
+++ b/activerecord/test/cases/validations/absence_validation_test.rb
@@ -72,4 +72,18 @@ class AbsenceValidationTest < ActiveRecord::TestCase
assert man.valid?
end
end
+
+ def test_validates_absence_of_virtual_attribute_on_model
+ repair_validations(Interest) do
+ Interest.send(:attr_accessor, :token)
+ Interest.validates_absence_of(:token)
+
+ interest = Interest.create!(topic: 'Thought Leadering')
+ assert interest.valid?
+
+ interest.token = 'tl'
+
+ assert interest.invalid?
+ end
+ end
end
diff --git a/activerecord/test/cases/validations/length_validation_test.rb b/activerecord/test/cases/validations/length_validation_test.rb
index c5d8f8895c..624aeaaddb 100644
--- a/activerecord/test/cases/validations/length_validation_test.rb
+++ b/activerecord/test/cases/validations/length_validation_test.rb
@@ -74,4 +74,20 @@ class LengthValidationTest < ActiveRecord::TestCase
assert owner.valid?
assert pet.valid?
end
+
+ def test_validates_presence_of_virtual_attribute_on_model
+ repair_validations(Pet) do
+ Pet.send(:attr_accessor, :nickname)
+ Pet.validates_length_of(:name, minimum: 1)
+ Pet.validates_length_of(:nickname, minimum: 1)
+
+ pet = Pet.create!(name: 'Fancy Pants', nickname: 'Fancy')
+
+ assert pet.valid?
+
+ pet.nickname = ''
+
+ assert pet.invalid?
+ end
+ end
end
diff --git a/activerecord/test/cases/validations/presence_validation_test.rb b/activerecord/test/cases/validations/presence_validation_test.rb
index 6f8ad06ab6..691f10a635 100644
--- a/activerecord/test/cases/validations/presence_validation_test.rb
+++ b/activerecord/test/cases/validations/presence_validation_test.rb
@@ -80,4 +80,19 @@ class PresenceValidationTest < ActiveRecord::TestCase
assert man.valid?
end
end
+
+ def test_validates_presence_of_virtual_attribute_on_model
+ repair_validations(Interest) do
+ Interest.send(:attr_accessor, :abbreviation)
+ Interest.validates_presence_of(:topic)
+ Interest.validates_presence_of(:abbreviation)
+
+ interest = Interest.create!(topic: 'Thought Leadering', abbreviation: 'tl')
+ assert interest.valid?
+
+ interest.abbreviation = ''
+
+ assert interest.invalid?
+ end
+ end
end