Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Nested attribute setters can be overridden. #2945

merged 1 commit into from

7 participants


We needed to use some of the features of accepts_nested_attributes_for (such as :_destroy) but we needed to filter the incoming attributes. This patch puts the methods accepts_nested_attributes_for defines in a module which can sit behind a custom implementation so that it can call super.


I like this. However, instead of creating a new module, can't we simply use the original attributes module?


I don't think that's wise. ActiveModel::AttributeMethods owns that module, and this is independent of that system. For instance, calling attribute_method_prefix (or the other similar declarations) undefines all of the methods in that module. It would blow these away too, and not know to redefine them.


Good point. /cc @jonleighton @tenderlove


we should use the generated_feature_methods module


@Peeja any possibility of changing the pull request to use the generated_feature_methods module as per @jonleighton suggestion? Thanks.


Yep, it's been sitting on my list for...boy, 2 months? Yeah, I'll get on it.

Jonathan Mukai & Peter Jaros Nested attribute setters can be overridden.
Overriding implementation can call super.

Updated, but I'm having trouble getting the pull request to register the change. Please stand by.


Commenting seems to have done it. :)

Question: Now NestedAttributes depends on Core (for generated_feature_methods). Is that kosher? Or does that dependency need to be explicit somehow (like includeing Core, which doesn't seem right either).


I think we can just think that Core should always be there. @jonleighton any thought? Thanks.


Yeah that's fine. At the moment, the use of modules in AR is mainly for code organisation really - there are lots of dependencies between different modules. I'll merge this, thanks!

@jonleighton jonleighton merged commit 3a8c543 into from

Is there any chance of getting this into 3.2? There's a workaround, but calling super would be much nicer than calling assign_nested_attributes_for_collection_association. And we already have it for associations and normal attributes.


+1 for backporting to 3.2...

In the meantime, you can always do what I did and just copy and paste the fix into your project. Yay.


I don't think we should backport this since it is more a new feature that a bug fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 28, 2012
  1. @Peeja

    Nested attribute setters can be overridden.

    Jonathan Mukai & Peter Jaros authored Peeja committed
    Overriding implementation can call super.
This page is out of date. Refresh to see the latest.
2  activerecord/lib/active_record/nested_attributes.rb
@@ -288,7 +288,7 @@ def accepts_nested_attributes_for(*attr_names)
# def pirate_attributes=(attributes)
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes, mass_assignment_options)
# end
- class_eval <<-eoruby, __FILE__, __LINE__ + 1
+ generated_feature_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
if method_defined?(:#{association_name}_attributes=)
13 activerecord/test/cases/nested_attributes_test.rb
@@ -172,6 +172,19 @@ def test_first_and_array_index_zero_methods_return_the_same_value_when_nested_at
man.interests_attributes = [{:id =>, :topic => 'gardening'}]
assert_equal man.interests.first.topic, man.interests[0].topic
+ def test_allows_class_to_override_setter_and_call_super
+ mean_pirate_class = do
+ accepts_nested_attributes_for :parrot
+ def parrot_attributes=(attrs)
+ super(attrs.merge(:color => "blue"))
+ end
+ end
+ mean_pirate =
+ mean_pirate.parrot_attributes = { :name => "James" }
+ assert_equal "James",
+ assert_equal "blue", mean_pirate.parrot.color
+ end
class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
1  activerecord/test/schema/schema.rb
@@ -439,6 +439,7 @@ def create_table(*args, &block)
create_table :parrots, :force => true do |t|
t.column :name, :string
+ t.column :color, :string
t.column :parrot_sti_class, :string
t.column :killer_id, :integer
t.column :created_at, :datetime
Something went wrong with that request. Please try again.