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:



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

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:



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

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:



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

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:



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

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

#_protobuf_field_symbol_transformersObject

:nodoc:



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

def _protobuf_field_symbol_transformers
  self.class._protobuf_field_symbol_transformers
end

#_protobuf_field_transformersObject

:nodoc:



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

def _protobuf_field_transformers
  self.class._protobuf_field_transformers
end

#_protobuf_messageObject

:nodoc:



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

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)


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

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.class.__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:



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

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

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