module ActiveRecord::NestedAttributes::ClassMethods

def accepts_nested_attributes_for(*attr_names)

accepts_nested_attributes_for :avatar, :posts, allow_destroy: true
# creates avatar_attributes= and posts_attributes=
accepts_nested_attributes_for :avatar, reject_if: :all_blank
# creates avatar_attributes=
accepts_nested_attributes_for :avatar, reject_if: proc { |attributes| attributes['name'].blank? }
# creates avatar_attributes=
Examples:

associations.
whether the :id is present. The option is ignored for collection
are used to update the record's attributes always, regardless of
However if the +:update_only+ option is +true+, the nested attributes
record will be instantiated and used to replace the existing one.
if they include the record's :id value. Otherwise a new
and the nested attributes are used to update the existing record only
containing those values. By default the +:update_only+ option is +false+
new set of attribute values or be replaced by a wholly new record
exists. In general, an existing record may either be updated with the
nested attributes are going to be used when an associated record already
For a one-to-one association, this option allows you to specify how
[:update_only]
associations.
Note that the +:limit+ option is only applicable to one-to-many
number of associations can be processed.
NestedAttributes::TooManyRecords exception is raised. If omitted, any
If the size of the nested attributes array exceeds the specified limit,
as a Proc or a Symbol pointing to a method that should return a number.
can be processed with the nested attributes. Limit also can be specified
Allows you to specify the maximum number of associated records that
[:limit]
any value for +_destroy+.
that will reject a record where all the attributes are blank excluding
Passing :all_blank instead of a Proc will create a proc
do not have a _destroy value that evaluates to true.
is specified, a record will be built for all attribute hashes that
and it should return either +true+ or +false+. When no +:reject_if+
hash. The hash is passed to the supplied Proc or the method
that checks whether a record should be built for a certain attribute
Allows you to specify a Proc or a Symbol pointing to a method
[:reject_if]
(e.g. 1, '1', true, or 'true'). This option is off by default.
_destroy key and a value that evaluates to +true+
If true, destroys any members from the attributes hash with a
[:allow_destroy]
Supported options:

Defines an attributes writer for the specified association(s).
def accepts_nested_attributes_for(*attr_names)
  options = { allow_destroy: false, update_only: false }
  options.update(attr_names.extract_options!)
  options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
  options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
  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
      self.nested_attributes_options = nested_attributes_options
      type = (reflection.collection? ? :collection : :one_to_one)
      generate_association_writer(association_name, type)
    else
      raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
    end
  end
end

def generate_association_writer(association_name, type)

associations are just regular associations.
the helper methods defined below. Makes it seem like the nested
This redirects the attempts to write objects in an association through

end
assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
def pirate_attributes=(attributes)

could generate the following:
accessing the objects in the association. For example, this method
Generates a writer method for this association. Serves as a point for
def generate_association_writer(association_name, type)
  generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
    silence_redefinition_of_method :#{association_name}_attributes=
    def #{association_name}_attributes=(attributes)
      assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
    end
  eoruby
end