Module: Protobuf::ActiveRecord::Serialization

Extended by:
ActiveSupport::Concern
Defined in:
lib/protobuf/active_record/serialization.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#_filter_field_attributes(options = {}) ⇒ Object

:nodoc:



235
236
237
238
239
240
241
242
243
# File 'lib/protobuf/active_record/serialization.rb', line 235

def _filter_field_attributes(options = {})
  options = _normalize_options(options)

  fields = _filtered_fields(options)
  fields &= [ options[:only] ].flatten if options[:only].present?
  fields -= [ options[:except] ].flatten if options[:except].present?

  fields
end

#_filtered_fields(options = {}) ⇒ Object

:nodoc:



246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/protobuf/active_record/serialization.rb', line 246

def _filtered_fields(options = {})
  include_deprecated = options.fetch(:deprecated, true)

  fields = []
  fields.concat(self.class._protobuf_message_non_deprecated_fields)
  fields.concat(self.class._protobuf_message_deprecated_fields) if include_deprecated
  fields.concat([options[:include]].flatten) if options[:include].present?
  fields.compact!
  fields.uniq!

  fields
end

#_is_collection_association?(field) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


260
261
262
263
264
265
# File 'lib/protobuf/active_record/serialization.rb', line 260

def _is_collection_association?(field)
  reflection = self.class.reflect_on_association(field)
  return false unless reflection

  reflection.macro == :has_many
end

#_normalize_options(options) ⇒ Object

:nodoc:



268
269
270
271
272
273
274
# File 'lib/protobuf/active_record/serialization.rb', line 268

def _normalize_options(options)
  options ||= {}
  options[:only] ||= [] if options.fetch(:except, false)
  options[:except] ||= [] if options.fetch(:only, false)

  self.class._protobuf_field_options.merge(options)
end

#_protobuf_field_symbol_transformersObject

:nodoc:



335
336
337
# File 'lib/protobuf/active_record/serialization.rb', line 335

def _protobuf_field_symbol_transformers
  self.class._protobuf_field_symbol_transformers
end

#_protobuf_field_transformersObject

:nodoc:



340
341
342
# File 'lib/protobuf/active_record/serialization.rb', line 340

def _protobuf_field_transformers
  self.class._protobuf_field_transformers
end

#_protobuf_messageObject

:nodoc:



345
346
347
# File 'lib/protobuf/active_record/serialization.rb', line 345

def _protobuf_message
  self.class.protobuf_message
end

#fields_from_record(options = {}) ⇒ Object

Extracts attributes that correspond to fields on the specified protobuf message, performing any necessary column conversions on them. Accepts a hash of options for specifying which fields should be serialized.

Examples:

fields_from_record(:only => [ :guid, :name ])
fields_from_record(:except => :email_domain)
fields_from_record(:include => :email_domain)
fields_from_record(:except => :email_domain, :deprecated => false)


286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/protobuf/active_record/serialization.rb', line 286

def fields_from_record(options = {})
  hash = {}
  field_attributes = _filter_field_attributes(options)

  # Already flattened / compacted / uniqued ... unless we must include
  if options[:include].present?
    field_attributes.concat([ options[:include] ].flatten)
    field_attributes.compact!
    field_attributes.uniq!
  end

  attribute_number = 0
  limit = field_attributes.size

  # One of the very few places the diff between each/while can make a difference
  # in terms of optimization (`while` is slightly faster as no block carried through)
  while attribute_number < limit
    field = field_attributes[attribute_number]

    begin
      hash[field] = __send__("_protobuf_active_record_serialize_#{field}")
    rescue NoMethodError => error
      raise unless error.message =~ /_protobuf_active_record_serialize/i

      case
      when _protobuf_field_symbol_transformers.has_key?(field) then
        self.class._protobuf_write_symbol_transformer_method(field)
      when _protobuf_field_transformers.has_key?(field) then
        self.class._protobuf_write_field_transformer_method(field)
      when respond_to?(field) then
        if _is_collection_association?(field)
          self.class._protobuf_write_collection_assocation_method(field)
        else
          self.class._protobuf_write_convert_to_fields_method(field)
        end
      else
        self.class._protobuf_write_nil_method(field)
      end

      hash[field] = __send__("_protobuf_active_record_serialize_#{field}")
    end

    attribute_number += 1
  end

  hash
end

#to_proto(options = {}) ⇒ Object

:nodoc:

Raises:



350
351
352
353
354
355
# File 'lib/protobuf/active_record/serialization.rb', line 350

def to_proto(options = {})
  raise MessageNotDefined.new(self.class) if _protobuf_message.nil?

  fields = self.fields_from_record(options)
  _protobuf_message.new(fields)
end