module NestedStoreAttributes::AcceptsStoreAttributes::ClassMethods

Constants

REJECT_ALL_BLANK_PROC

Public Instance Methods

accepts_store_attributes_for(*attr_names) click to toggle source

Defines an attributes writer for the specified serialized attribute(s).

Supported options:

:allow_destroy

If true, destroys any members from the attributes hash with a _destroy key and a value that evaluates to true (eg. 1, ‘1’, true, or ‘true’). This option is off by default.

:reject_if

Allows you to specify a Proc or a Symbol pointing to a method that checks whether a record should be built for a certain attribute hash. The hash is passed to the supplied Proc or the method and it should return either true or false. When no :reject_if is specified, a record will be built for all attribute hashes that do not have a _destroy value that evaluates to true. Passing :all_blank instead of a Proc will create a proc that will reject a record where all the attributes are blank excluding any value for _destroy.

:limit

Allows you to specify the maximum number of the nested records that can be processed with the nested attributes. Limit also can be specified as a Proc or a Symbol pointing to a method that should return number. If the size of the nested attributes array exceeds the specified limit, NestedAttributes::TooManyRecords exception is raised. If omitted, any number nested records can be processed.

:primary_key

Allows you to specify the primary key to use when checking for existing objects. This defaults to :id.

Examples:

# creates subscribers_attributes=
accepts_store_attributes_for :subscribers, primary_key: :email
# creates books_attributes=
accepts_store_attributes_for :books, reject_if: proc { |attributes| attributes['name'].blank? }
# creates books_attributes=
accepts_store_attributes_for :books, reject_if: :all_blank
# creates books_attributes= and posts_attributes=
accepts_store_attributes_for :books, :posts, allow_destroy: true
# File lib/nested_store_attributes/accepts_store_attributes.rb, line 56
def accepts_store_attributes_for(*attr_names)
  options = { :allow_destroy => false, :update_only => false, :primary_key => :id }
  options.update(attr_names.extract_options!)
  options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only, :primary_key)
  options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank

  attr_names.each do |attribute_name|
    if self.attribute_names.include?(attribute_name.to_s)

      store_attributes_options = self.store_attributes_options.dup
      store_attributes_options[attribute_name] = options
      self.store_attributes_options = store_attributes_options

      store_generate_collection_writer(attribute_name)
    else
      raise ArgumentError, "No column found for name `#{attribute_name}'. Has it been added yet?"
    end
  end
end

Private Instance Methods

store_generate_collection_writer(attribute_name) click to toggle source

Generates a writer method for this attribute. Serves as a point for accessing the hashes in the attribute. For example, this method could generate the following:

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

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

# File lib/nested_store_attributes/accepts_store_attributes.rb, line 89
      def store_generate_collection_writer(attribute_name)
        generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
          if method_defined?(:#{attribute_name}_attributes=)
            remove_method(:#{attribute_name}_attributes=)
          end
          def #{attribute_name}_attributes=(attributes)
            store_assign_nested_attributes_for_collection(:#{attribute_name}, attributes)
          end
        eoruby
      end