diff options
Diffstat (limited to 'activerecord/lib/active_record/validations')
4 files changed, 35 insertions, 12 deletions
diff --git a/activerecord/lib/active_record/validations/absence.rb b/activerecord/lib/active_record/validations/absence.rb new file mode 100644 index 0000000000..2e19e6dc5c --- /dev/null +++ b/activerecord/lib/active_record/validations/absence.rb @@ -0,0 +1,24 @@ +module ActiveRecord + module Validations + class AbsenceValidator < ActiveModel::Validations::AbsenceValidator # :nodoc: + def validate_each(record, attribute, association_or_value) + return unless should_validate?(record) + if record.class._reflect_on_association(attribute) + association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?) + end + super + end + end + + module ClassMethods + # Validates that the specified attributes are not present (as defined by + # Object#present?). If the attribute is an association, the associated object + # is considered absent if it was marked for destruction. + # + # See ActiveModel::Validations::HelperMethods.validates_absence_of for more information. + def validates_absence_of(*attr_names) + validates_with AbsenceValidator, _merge_attributes(attr_names) + end + end + end +end diff --git a/activerecord/lib/active_record/validations/length.rb b/activerecord/lib/active_record/validations/length.rb index 5991fbad8e..69e048eef1 100644 --- a/activerecord/lib/active_record/validations/length.rb +++ b/activerecord/lib/active_record/validations/length.rb @@ -22,7 +22,10 @@ module ActiveRecord end module ClassMethods - # See <tt>ActiveModel::Validation::LengthValidator</tt> for more information. + # Validates that the specified attributes match the length restrictions supplied. + # If the attribute is an association, records that are marked for destruction are not counted. + # + # See ActiveModel::Validations::HelperMethods.validates_length_of for more information. def validates_length_of(*attr_names) validates_with LengthValidator, _merge_attributes(attr_names) end diff --git a/activerecord/lib/active_record/validations/presence.rb b/activerecord/lib/active_record/validations/presence.rb index a9b791397b..23a3985d35 100644 --- a/activerecord/lib/active_record/validations/presence.rb +++ b/activerecord/lib/active_record/validations/presence.rb @@ -1,18 +1,12 @@ module ActiveRecord module Validations class PresenceValidator < ActiveModel::Validations::PresenceValidator # :nodoc: - def validate(record) + def validate_each(record, attribute, association_or_value) return unless should_validate?(record) - super - attributes.each do |attribute| - next unless record.class._reflect_on_association(attribute) - associated_records = Array.wrap(record.send(attribute)) - - # Superclass validates presence. Ensure present records aren't about to be destroyed. - if associated_records.present? && associated_records.all?(&:marked_for_destruction?) - record.errors.add(attribute, :blank, options) - end + if record.class._reflect_on_association(attribute) + association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?) end + super end end diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 5106f4e127..32d17a1392 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -17,7 +17,9 @@ module ActiveRecord value = map_enum_attribute(finder_class, attribute, value) relation = build_relation(finder_class, table, attribute, value) - relation = relation.where.not(finder_class.primary_key => record.id) if record.persisted? + if record.persisted? && finder_class.primary_key.to_s != attribute.to_s + relation = relation.where.not(finder_class.primary_key => record.id) + end relation = scope_relation(record, table, relation) relation = relation.merge(options[:conditions]) if options[:conditions] |