aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/validations
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/validations')
-rw-r--r--activerecord/lib/active_record/validations/associated.rb13
-rw-r--r--activerecord/lib/active_record/validations/presence.rb7
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb10
3 files changed, 19 insertions, 11 deletions
diff --git a/activerecord/lib/active_record/validations/associated.rb b/activerecord/lib/active_record/validations/associated.rb
index 47ccef31a5..b14db85167 100644
--- a/activerecord/lib/active_record/validations/associated.rb
+++ b/activerecord/lib/active_record/validations/associated.rb
@@ -2,10 +2,16 @@ module ActiveRecord
module Validations
class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
def validate_each(record, attribute, value)
- if Array.wrap(value).reject {|r| r.marked_for_destruction? || r.valid?}.any?
- record.errors.add(attribute, :invalid, options.merge(:value => value))
+ if Array(value).reject { |r| valid_object?(r) }.any?
+ record.errors.add(attribute, :invalid, options.merge(value: value))
end
end
+
+ private
+
+ def valid_object?(record)
+ (record.respond_to?(:marked_for_destruction?) && record.marked_for_destruction?) || record.valid?
+ end
end
module ClassMethods
@@ -24,7 +30,8 @@ module ActiveRecord
#
# NOTE: This validation will not fail if the association hasn't been
# assigned. If you want to ensure that the association is both present and
- # guaranteed to be valid, you also need to use +validates_presence_of+.
+ # guaranteed to be valid, you also need to use
+ # {validates_presence_of}[rdoc-ref:Validations::ClassMethods#validates_presence_of].
#
# Configuration options:
#
diff --git a/activerecord/lib/active_record/validations/presence.rb b/activerecord/lib/active_record/validations/presence.rb
index 23a3985d35..7e85ed43ac 100644
--- a/activerecord/lib/active_record/validations/presence.rb
+++ b/activerecord/lib/active_record/validations/presence.rb
@@ -31,7 +31,7 @@ module ActiveRecord
# This is due to the way Object#blank? handles boolean values:
# <tt>false.blank? # => true</tt>.
#
- # This validator defers to the ActiveModel validation for presence, adding the
+ # This validator defers to the Active Model validation for presence, adding the
# check to see that an associated object is not marked for destruction. This
# prevents the parent object from validating successfully and saving, which then
# deletes the associated object, thus putting the parent object into an invalid
@@ -39,7 +39,8 @@ module ActiveRecord
#
# NOTE: This validation will not fail while using it with an association
# if the latter was assigned but not valid. If you want to ensure that
- # it is both present and valid, you also need to use +validates_associated+.
+ # it is both present and valid, you also need to use
+ # {validates_associated}[rdoc-ref:Validations::ClassMethods#validates_associated].
#
# Configuration options:
# * <tt>:message</tt> - A custom error message (default is: "can't be blank").
@@ -57,7 +58,7 @@ module ActiveRecord
# or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The method,
# proc or string should return or evaluate to a +true+ or +false+ value.
# * <tt>:strict</tt> - Specifies whether validation should be strict.
- # See <tt>ActiveModel::Validation#validates!</tt> for more information.
+ # See ActiveModel::Validation#validates! for more information.
def validates_presence_of(*attr_names)
validates_with PresenceValidator, _merge_attributes(attr_names)
end
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 5706bbd903..edc1325b25 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -172,7 +172,8 @@ module ActiveRecord
#
# === Concurrency and integrity
#
- # Using this validation method in conjunction with ActiveRecord::Base#save
+ # Using this validation method in conjunction with
+ # {ActiveRecord::Base#save}[rdoc-ref:Persistence#save]
# does not guarantee the absence of duplicate record insertions, because
# uniqueness checks on the application level are inherently prone to race
# conditions. For example, suppose that two users try to post a Comment at
@@ -209,12 +210,12 @@ module ActiveRecord
# This could even happen if you use transactions with the 'serializable'
# isolation level. The best way to work around this problem is to add a unique
# index to the database table using
- # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the
- # rare case that a race condition occurs, the database will guarantee
+ # {connection.add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index].
+ # In the rare case that a race condition occurs, the database will guarantee
# the field's uniqueness.
#
# When the database catches such a duplicate insertion,
- # ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid
+ # {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] will raise an ActiveRecord::StatementInvalid
# exception. You can either choose to let this error propagate (which
# will result in the default Rails exception page being shown), or you
# can catch it and restart the transaction (e.g. by telling the user
@@ -230,7 +231,6 @@ module ActiveRecord
#
# The following bundled adapters throw the ActiveRecord::RecordNotUnique exception:
#
- # * ActiveRecord::ConnectionAdapters::MysqlAdapter.
# * ActiveRecord::ConnectionAdapters::Mysql2Adapter.
# * ActiveRecord::ConnectionAdapters::SQLite3Adapter.
# * ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.