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:



244
245
246
247
248
249
250
251
252
# File 'lib/protobuf/active_record/serialization.rb', line 244

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:



255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/protobuf/active_record/serialization.rb', line 255

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)


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

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:



277
278
279
280
281
282
283
# File 'lib/protobuf/active_record/serialization.rb', line 277

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_objects(field) ⇒ Object

:nodoc:



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/protobuf/active_record/serialization.rb', line 322

def _protobuf_field_objects(field)
  self.class._protobuf_field_objects[field] ||= if _protobuf_field_symbol_transformers.key?(field)

    self.class._protobuf_symbol_transformer_object(field)
  elsif _protobuf_field_transformers.key?(field)

    self.class._protobuf_field_transformer_object(field)
  elsif respond_to?(field)

    if _is_collection_association?(field)
      self.class._protobuf_collection_association_object(field)
    else
      self.class._protobuf_convert_to_fields_object(field)
    end
  else
    self.class._protobuf_nil_object(field)
  end
end

#_protobuf_field_symbol_transformersObject

:nodoc:



342
343
344
# File 'lib/protobuf/active_record/serialization.rb', line 342

def _protobuf_field_symbol_transformers
  self.class._protobuf_field_symbol_transformers
end

#_protobuf_field_transformersObject

:nodoc:



347
348
349
# File 'lib/protobuf/active_record/serialization.rb', line 347

def _protobuf_field_transformers
  self.class._protobuf_field_transformers
end

#_protobuf_messageObject

:nodoc:



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

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)


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
# File 'lib/protobuf/active_record/serialization.rb', line 295

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]
    field_object = _protobuf_field_objects(field)
    hash[field] = field_object.call(self)
    attribute_number += 1
  end

  hash
end

#to_proto(options = {}) ⇒ Object

:nodoc:

Raises:



357
358
359
360
361
362
# File 'lib/protobuf/active_record/serialization.rb', line 357

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

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