mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Improve support for non Active Record objects on validates_associated
Skipping `marked_for_destruction?` when the associated object does not responds to it make easier to validate virtual associations built on top of Active Model objects and/or serialized objects that implement a `valid?` instance method.
This commit is contained in:
parent
25673f47b6
commit
c8bbe9aefa
3 changed files with 28 additions and 2 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
* Improve support for non Active Record objects on `validates_associated`
|
||||||
|
|
||||||
|
Skipping `marked_for_destruction?` when the associated object does not responds
|
||||||
|
to it make easier to validate virtual associations built on top of Active Model
|
||||||
|
objects and/or serialized objects that implement a `valid?` instance method.
|
||||||
|
|
||||||
|
*Kassio Borges*, *Lucas Mazza*
|
||||||
|
|
||||||
* Change connection management middleware to return a new response with
|
* Change connection management middleware to return a new response with
|
||||||
a body proxy, rather than mutating the original.
|
a body proxy, rather than mutating the original.
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,16 @@ module ActiveRecord
|
||||||
module Validations
|
module Validations
|
||||||
class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
|
class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
|
||||||
def validate_each(record, attribute, value)
|
def validate_each(record, attribute, value)
|
||||||
if Array.wrap(value).reject {|r| r.marked_for_destruction? || r.valid?}.any?
|
if Array(value).reject { |r| valid_object?(r) }.any?
|
||||||
record.errors.add(attribute, :invalid, options.merge(:value => value))
|
record.errors.add(attribute, :invalid, options.merge(value: value))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def valid_object?(record)
|
||||||
|
(record.respond_to?(:marked_for_destruction?) && record.marked_for_destruction?) || record.valid?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
|
|
|
@ -45,6 +45,18 @@ class AssociationValidationTest < ActiveRecord::TestCase
|
||||||
assert t.valid?
|
assert t.valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_validates_associated_without_marked_for_destruction
|
||||||
|
reply = Class.new do
|
||||||
|
def valid?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Topic.validates_associated(:replies)
|
||||||
|
t = Topic.new
|
||||||
|
t.define_singleton_method(:replies) { [reply.new] }
|
||||||
|
assert t.valid?
|
||||||
|
end
|
||||||
|
|
||||||
def test_validates_associated_with_custom_message_using_quotes
|
def test_validates_associated_with_custom_message_using_quotes
|
||||||
Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes"
|
Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes"
|
||||||
Topic.validates_presence_of :content
|
Topic.validates_presence_of :content
|
||||||
|
|
Loading…
Reference in a new issue