Always perform validations on nested attribute associations

Collection associations would have already been validated, but singular
associations were not.

Fixes #18735.
This commit is contained in:
Sean Griffin 2015-01-30 07:26:33 -07:00
parent 5170c11c97
commit 85465ed3e6
4 changed files with 22 additions and 5 deletions

@ -177,10 +177,8 @@ def define_non_cyclic_method(name, &block)
# before actually defining them.
def add_autosave_association_callbacks(reflection)
save_method = :"autosave_associated_records_for_#{reflection.name}"
validation_method = :"validate_associated_records_for_#{reflection.name}"
collection = reflection.collection?
if collection
if reflection.collection?
before_save :before_save_collection_association
define_non_cyclic_method(save_method) { save_collection_association(reflection) }
@ -204,8 +202,18 @@ def add_autosave_association_callbacks(reflection)
before_save save_method
end
define_autosave_validation_callbacks(reflection)
end
def define_autosave_validation_callbacks(reflection)
validation_method = :"validate_associated_records_for_#{reflection.name}"
if reflection.validate? && !method_defined?(validation_method)
method = (collection ? :validate_collection_association : :validate_single_association)
if reflection.collection?
method = :validate_collection_association
else
method = :validate_single_association
end
define_non_cyclic_method(validation_method) do
send(method, reflection)
# TODO: remove the following line as soon as the return value of

@ -312,6 +312,7 @@ def accepts_nested_attributes_for(*attr_names)
attr_names.each do |association_name|
if reflection = _reflect_on_association(association_name)
reflection.autosave = true
define_autosave_validation_callbacks(reflection)
nested_attributes_options = self.nested_attributes_options.dup
nested_attributes_options[association_name.to_sym] = options

@ -1047,4 +1047,11 @@ def setup
ship.save!
end
end
test "nested singular associations are validated" do
part = ShipPart.new(name: "Stern", ship_attributes: { name: nil })
assert_not part.valid?
assert_equal ["Ship name can't be blank"], part.errors.full_messages
end
end

@ -2,6 +2,7 @@ class ShipPart < ActiveRecord::Base
belongs_to :ship
has_many :trinkets, :class_name => "Treasure", :as => :looter
accepts_nested_attributes_for :trinkets, :allow_destroy => true
accepts_nested_attributes_for :ship
validates_presence_of :name
end
end