Module: Protobuf::ActiveRecord::Transformation::ClassMethods

Defined in:
lib/protobuf/active_record/transformation.rb

Instance Method Summary collapse

Instance Method Details

#_filter_attribute_fields(proto) ⇒ Object

Filters accessible attributes that exist in the given protobuf message’s fields or have attribute transformers defined for them.

Returns a hash of attribute fields with their respective values.

:nodoc:



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/protobuf/active_record/transformation.rb', line 29

def _filter_attribute_fields(proto)
  fields = proto.to_hash
  fields.select! do |key, value|
    field = proto.class.get_field(key, true)
    proto.field?(key) && !field.repeated?
  end

  filtered_attributes = _filtered_attributes + _protobuf_nested_attributes
  filtered_attributes += _protobuf_attribute_transformers.keys

  attribute_fields = filtered_attributes.inject({}) do |hash, column_name|
    symbolized_column = column_name.to_sym

    if fields.has_key?(symbolized_column) ||
      _protobuf_attribute_transformers.has_key?(symbolized_column)
      hash[symbolized_column] = fields[symbolized_column]
    end

    hash
  end

  attribute_fields
end

#_filtered_attributesObject

Overidden by mass assignment security when protected attributes is loaded.

:nodoc:



56
57
58
# File 'lib/protobuf/active_record/transformation.rb', line 56

def _filtered_attributes
  return self.attribute_names
end

#_protobuf_convert_fields_to_attributes(key, value) ⇒ Object

:nodoc:



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/protobuf/active_record/transformation.rb', line 61

def _protobuf_convert_fields_to_attributes(key, value)
  return value if value.nil?

  value = case
          when !_protobuf_date_datetime_time_or_timestamp_column?(key) then
            value
          when _protobuf_date_column?(key) then
            convert_int64_to_date(value)
          when _protobuf_datetime_column?(key) then
            convert_int64_to_datetime(value)
          when _protobuf_time_column?(key) then
            convert_int64_to_time(value)
          when _protobuf_timestamp_column?(key) then
            convert_int64_to_time(value)
          else
            value
          end

  return value
end

#attribute_from_proto(attribute, *args, &block) ⇒ Object

Define an attribute transformation from protobuf. Accepts a Symbol, callable, or block.

When given a callable or block, it is directly used to convert the field.

When a symbol is given, it extracts the method with the same name.

The callable or method must accept a single parameter, which is the proto message.

Examples:

attribute_from_proto :public_key, :extract_public_key_from_proto
attribute_from_proto :status, lambda { |proto| # Do some stuff... }
attribute_from_proto :status do |proto|
  # Do some blocky stuff...
end

attribute_from_proto :status, lambda { |proto| nil }, :nullify_on => :status
attribute_from_proto :status, :nullify_on => :status do |proto|
  nil
end


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/protobuf/active_record/transformation.rb', line 104

def attribute_from_proto(attribute, *args, &block)
  options = args.extract_options!
  symbol_or_block = args.first || block

  if symbol_or_block.is_a?(Symbol)
    callable = lambda { |value| self.__send__(symbol_or_block, value) }
  else
    raise AttributeTransformerError unless symbol_or_block.respond_to?(:call)
    callable = symbol_or_block
  end

  if options[:nullify_on]
    field = protobuf_message.get_field(:nullify)
    unless field && field.is_a?(::Protobuf::Field::StringField) && field.repeated?
      ::Protobuf::Logging.logger.warn "Message: #{protobuf_message} is not compatible with :nullify_on option"
    end
  end

  transformer = ::Protobuf::ActiveRecord::Transformer.new(callable, options)
  _protobuf_attribute_transformers[attribute.to_sym] = transformer
end

#attributes_from_proto(proto) ⇒ Object

Creates a hash of attributes from a given protobuf message.

It converts and transforms field values using the field converters and attribute transformers, ignoring repeated and nil fields.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/protobuf/active_record/transformation.rb', line 132

def attributes_from_proto(proto)
  attribute_fields = _filter_attribute_fields(proto)

  attributes = attribute_fields.inject({}) do |hash, (key, value)|
    if _protobuf_attribute_transformers.has_key?(key)
      transformer = _protobuf_attribute_transformers[key]
      attribute = transformer.call(proto)
      hash[key] = attribute unless attribute.nil?
      hash[key] = nil if transformer.nullify?(proto)
    else
      hash[key] = _protobuf_convert_fields_to_attributes(key, value)
    end

    hash
  end

  return attributes unless proto.field?(:nullify) && proto.nullify.is_a?(Array)

  proto.nullify.each do |attribute_name|
    attributes[attribute_name.to_sym] = nil if attribute_names.include?(attribute_name.to_s)
  end

  attributes
end

#convert_int64_to_date(int64) ⇒ Object

:nodoc:



163
164
165
# File 'lib/protobuf/active_record/transformation.rb', line 163

def convert_int64_to_date(int64)
  convert_int64_to_time(int64).utc.to_date
end

#convert_int64_to_datetime(int64) ⇒ Object

:nodoc:



168
169
170
# File 'lib/protobuf/active_record/transformation.rb', line 168

def convert_int64_to_datetime(int64)
  convert_int64_to_time(int64).to_datetime
end

#convert_int64_to_time(int64) ⇒ Object

:nodoc:



158
159
160
# File 'lib/protobuf/active_record/transformation.rb', line 158

def convert_int64_to_time(int64)
  Time.at(int64.to_i)
end