Module: AcceptsFlattenedValues::Mixin::ClassMethods

Defined in:
lib/accepts_flattened_values/mixin.rb

Instance Method Summary collapse

Instance Method Details

#accepts_flattened_values_for(*attr_names) ⇒ Object

Flattened Values

Flattened values allow you to save single value entities in a has_many or has_and_belongs_to_many association. By default flattened values updating is turned off, you can enable it using the accepts_flattened_values_for class method. When you enable flattened values an attribute writer is defined on the model.

The attribute writer is named after the association, which means that in the following example, two new methods are added to your model: interests_values=(values) and skills_values=(values).

class User < ActiveRecord::Base
  has_many :interests
  has_many :skills

  accepts_nested_attributes_for :interests, :skills
end

Note that the :autosave option is automatically enabled on every association that accepts_flattened_values_for is used for.

Options

  • :separator the separator used to join and split the string value. Defaults to ‘,’

  • :value the field to use for the string values on the associatied model. Defaults to ‘:value’



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/accepts_flattened_values/mixin.rb', line 37

def accepts_flattened_values_for(*attr_names)
  options = { :separator => ',', :value => :value }
  options.update(attr_names.extract_options!)
  options.assert_valid_keys(:separator, :value)

  attr_names.each do |association_name|
    if reflection = reflect_on_association(association_name)
      reflection.options[:autosave] = true
      add_autosave_association_callbacks(reflection)
      flattened_values_options[association_name.to_sym] = options
      flattened_values_klasses[association_name.to_sym] = reflection.klass

      unless reflection.collection?
        raise ArugmentError, "Assocation `#{association_name}' must be a collection."
      end

      # def pirate_values
      #   get_flattened_values_for_association(:pirate)
      # end
      #
      # def pirate_values=(values)
      #   assign_flattened_values_for_association(:pirate, values)
      # end
      class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
        if method_defined?(:#{association_name}_values)
          remove_method(:#{association_name}_values)
        end
        def #{association_name}_values
          get_flattened_values_for_association(:#{association_name})
        end

        if method_defined?(:#{association_name}_values=)
          remove_method(:#{association_name}_values=)
        end
        def #{association_name}_values=(values)
          assign_flattened_values_for_association(:#{association_name}, values)
        end
      RUBY_EVAL
    else
      raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
    end
  end
end