Module: PersonName::ActiveRecord::Core::InstanceMethods

Defined in:
lib/person_name/has_person_name.rb

Instance Method Summary collapse

Instance Method Details

#attributes=(new_attributes) ⇒ Object

when using forms to edit the full name or the indiviual form parts it is possible that both fields (The aggregated one and the individual ones) get posted back to the model. So, wich fields are the correct edited ones?

To determine this, we use this development mantra:

  1. If the user is able to edit it in one field, he should.

Therefore, if the aggregated field is posted, this is the most recent one
and should override the seperated parts
  1. If only individual parts are edited, there should not be an aggregated

value in the form
  1. If the view allowes the user to edit the aggregated field and the seperated fields,

the field should make sure the values are comparable (eg. the separated values combined
should be equal to the aggregated one). If this is the case, the separated fields
will rule over the aggregated one, since it is more detailed and adds up to the same result.


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/person_name/has_person_name.rb', line 107

def attributes=(new_attributes)
  return unless new_attributes.is_a?(Hash)
  attributes = new_attributes.stringify_keys

  self.class.name_types.map(&:to_s).each do |name_base|
    if attributes.has_key? name_base # only add behaviour if the full name is supplied
      full = attributes[name_base]

      existing_part_fields = []
      part_values = []
      part_hash = {}
      PersonName::NameSplitter::NAME_PARTS.each do |name_part|
        test_field = "#{name_base}_#{name_part}"
        if attributes.has_key? test_field
          existing_part_fields << test_field
          part_values << attributes[test_field]
          part_hash[name_part.to_sym] = attributes[test_field]
        else
          part_values << send(test_field.to_sym)
        end
      end
      if part_values.compact.join(" ") == full
        attributes.delete name_base
      else
        # try to use existing fields as editing values of full name
        new_part_values = PersonName::NameSplitter.split(attributes[name_base], part_hash)
        assignments_valid = nil

        # test if there is no conflict
        PersonName::NameSplitter::NAME_PARTS.each do |name_part|
          test_field = "#{name_base}_#{name_part}"
          if attributes.has_key? test_field
            attributes[test_field] = new_part_values[name_part.to_sym]
            assignments_valid = true if assignments_valid.nil?
          else
            assignments_valid = false unless new_part_values[name_part.to_sym].nil?
          end
        end

        if assignments_valid
          attributes.delete name_base
        else
          existing_part_fields.each do |part_field|
            attributes.delete part_field
          end
        end
      end
    end
  end

  super attributes
end