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:



161
162
163
164
165
166
167
168
169
# File 'lib/protobuf/active_record/serialization.rb', line 161

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:



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/protobuf/active_record/serialization.rb', line 172

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

#_normalize_options(options) ⇒ Object

:nodoc:



186
187
188
189
190
191
192
# File 'lib/protobuf/active_record/serialization.rb', line 186

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_convert_attributes_to_fields(field, value) ⇒ Object

:nodoc:



243
244
245
# File 'lib/protobuf/active_record/serialization.rb', line 243

def _protobuf_convert_attributes_to_fields(field, value)
  self.class._protobuf_convert_attributes_to_fields(field, value)
end

#_protobuf_field_symbol_transformersObject

:nodoc:



248
249
250
# File 'lib/protobuf/active_record/serialization.rb', line 248

def _protobuf_field_symbol_transformers
  self.class._protobuf_field_symbol_transformers
end

#_protobuf_field_transformersObject

:nodoc:



253
254
255
# File 'lib/protobuf/active_record/serialization.rb', line 253

def _protobuf_field_transformers
  self.class._protobuf_field_transformers
end

#_protobuf_messageObject

:nodoc:



258
259
260
# File 'lib/protobuf/active_record/serialization.rb', line 258

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)


204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/protobuf/active_record/serialization.rb', line 204

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]
    hash[field] = case
                  when _protobuf_field_symbol_transformers.has_key?(field) then
                    self.__send__(_protobuf_field_symbol_transformers[field], self)
                  when _protobuf_field_transformers.has_key?(field) then
                    _protobuf_field_transformers[field].call(self)
                  when self.class._protobuf_instance_respond_to_from_cache?(field) then
                    _protobuf_convert_attributes_to_fields(field, __send__(field))
                  when respond_to?(field) then
                    self.class._protobuf_respond_to_cache << field
                    _protobuf_convert_attributes_to_fields(field, __send__(field))
                  else
                    nil
                  end

    attribute_number += 1
  end

  hash
end

#to_proto(options = {}) ⇒ Object

:nodoc:

Raises:



263
264
265
266
267
268
# File 'lib/protobuf/active_record/serialization.rb', line 263

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

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