Module: Netzke::DataMapper::Attributes

Extended by:
ActiveSupport::Concern
Defined in:
lib/netzke/data_mapper/attributes.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#netzke_array(attributes = self.class.netzke_attributes) ⇒ Object

Transforms a record to array of values according to the passed attributes



166
167
168
169
170
171
172
173
# File 'lib/netzke/data_mapper/attributes.rb', line 166

def netzke_array(attributes = self.class.netzke_attributes)
  res = []
  for a in attributes
    next if a[:included] == false
    res << value_for_attribute(a, a[:nested_attribute])
  end
  res
end

#netzke_hash(attributes = self.class.netzke_attributes) ⇒ Object

Accepts both hash and array of attributes



180
181
182
183
184
185
186
187
# File 'lib/netzke/data_mapper/attributes.rb', line 180

def netzke_hash(attributes = self.class.netzke_attributes)
  res = {}
  for a in (attributes.is_a?(Hash) ? attributes.values : attributes)
    next if a[:included] == false
    res[a[:name].to_sym] = self.value_for_attribute(a, a[:nested_attribute])
  end
  res
end

#netzke_jsonObject



175
176
177
# File 'lib/netzke/data_mapper/attributes.rb', line 175

def netzke_json
  netzke_hash.to_nifty_json
end

#set_value_for_attribute(a, v) ⇒ Object

Assigns new value to an (association) attribute



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/netzke/data_mapper/attributes.rb', line 222

def set_value_for_attribute(a, v)
  v = v.to_time_in_current_zone if v.is_a?(Date) # convert Date to Time

  if a[:setter]
    a[:setter].call(self, v)
  elsif respond_to?("#{a[:name]}=")
    send("#{a[:name]}=", v)
  elsif is_association_attr?(a)
    split = a[:name].to_s.split(/\.|__/)
    if a[:nested_attribute]
      # We want:
      #     set_value_for_attribute({:name => :assoc_1__assoc_2__method, :nested_attribute => true}, 100)
      # =>
      #     self.assoc_1.assoc_2.method = 100
      split.inject(self) { |r,m| m == split.last ? (r && r.send("#{m}=", v) && r.save) : r.send(m) }
    else
      if split.size == 2
        # search for association and assign it to self
        assoc_name, assoc_method = split
        relationship=self.class.relationships[assoc_name]

        if relationship
          if relationship.kind_of? ::DataMapper::Associations::OneToOne::Relationship
            assoc_instance=self.send(assoc_name)
            if assoc_instance
              assoc_instance.send("#{assoc_method}=", v)
              assoc_instance.save # what should we do when this fails?..
            else
              # what should we do in this case?
            end
          else
            self.send("#{self.class.data_adapter.foreign_key_for assoc_name}=", v)
          end
        else
          ::Rails.logger.debug "Netzke::Basepack: Association #{assoc} is not known for class #{self.class.name}"
        end
      else
        ::Rails.logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}"
      end
    end
  end
end

#value_for_attribute(a, through_association = false) ⇒ Object

Fetches the value specified by an (association) attribute If through_association is true, get the value of the association by provided method, not the associated record’s id E.g., author__name with through_association set to true may return “Vladimir Nabokov”, while with through_association set to false, it’ll return author_id for the current record



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/netzke/data_mapper/attributes.rb', line 192

def value_for_attribute(a, through_association = false)
  v = if a[:getter]
        a[:getter].call(self)
      elsif respond_to?("#{a[:name]}")
        send("#{a[:name]}")
      elsif is_association_attr?(a)
        split = a[:name].to_s.split(/\.|__/)
        assoc = self.class.relationships[split.first.to_sym]

        if through_association
          split.inject(self) do |r,m| # TODO: do we really need to descend deeper than 1 level?
            if r.respond_to?(m)
              r.send(m)
            else
              ::Rails.logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}" unless r.nil?
              nil
            end
          end
        else
          self.send assoc.child_key.first.name
        end
      end

  # a work-around for to_json not taking the current timezone into account when serializing ActiveSupport::TimeWithZone
  v = v.to_datetime.to_s(:db) if [ActiveSupport::TimeWithZone].include?(v.class)
  v = v.to_s(:db) if [DateTime, Date].include?(v.class)
  v
end