Module: Netzke::Sequel::Attributes

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

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(receiver) ⇒ Object



17
18
19
# File 'lib/netzke/sequel/attributes.rb', line 17

def self.included receiver
  receiver.extend ClassMethods
end

Instance Method Details

#attributesObject

AR compatibility



161
162
163
# File 'lib/netzke/sequel/attributes.rb', line 161

def attributes
  values
end

#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/sequel/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



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

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

convenience method to convert all netzke attributes of a model to nifty json



176
177
178
# File 'lib/netzke/sequel/attributes.rb', line 176

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
264
# File 'lib/netzke/sequel/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]}=")
    unless primary_key.to_s == a[:name] && v.blank? # In contrast to ActiveRecord, Sequel doesn't allow setting nil/NULL primary keys
      send("#{a[:name]}=", v)
    end
  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 = self.class.association_reflection(split.first.to_sym)
        assoc_method = split.last
        if assoc
          if assoc[:type] == :one_to_one
            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("#{assoc[:key]}=", v)
          end
        else
          logger.debug "Netzke::Basepack: Association #{assoc} is not known for class #{self.class.name}"
        end
      else
        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



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/sequel/attributes.rb', line 193

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.association_reflection(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
              logger.debug "Netzke::Basepack: Wrong attribute name: #{a[:name]}" unless r.nil?
              nil
            end
          end
        else
          self.send("#{assoc[:key].to_s}")
        end
      end

  # need to serialize Date and Time objects with to_s :db for compatibility with client side
  # DATETIME fields in database are given as Time by Sequel
  v = v.to_s(:db) if [Date, Time].include?(v.class)
  v
end