Class: ActiveModel::Serializer

Inherits:
Object
  • Object
show all
Includes:
Serializable
Defined in:
lib/active_model/serializer.rb,
lib/active_model/serializer/config.rb,
lib/active_model/serializer/version.rb,
lib/active_model/serializer/association.rb,
lib/active_model/serializer/association/has_one.rb,
lib/active_model/serializer/association/has_many.rb

Defined Under Namespace

Classes: Association, Config

Constant Summary collapse

EMBED_IN_ROOT_OPTIONS =
[
  :include,
  :embed_in_root,
  :embed_in_root_key,
  :embed_namespace
].freeze
CONFIG =

:nodoc:

Config.new('embed' => :objects)
VERSION =
'0.9.4'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Serializable

#as_json, included, #namespace, #serializable_data, #serializable_object_with_notification

Constructor Details

#initialize(object, options = {}) ⇒ Serializer

Returns a new instance of Serializer.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/active_model/serializer.rb', line 134

def initialize(object, options={})
  @object        = object
  @scope         = options[:scope]
  @root          = options.fetch(:root, self.class._root)
  @polymorphic   = options.fetch(:polymorphic, false)
  @meta_key      = options[:meta_key] || :meta
  @meta          = options[@meta_key]
  @wrap_in_array = options[:_wrap_in_array]
  @only          = options[:only] ? Array(options[:only]) : nil
  @except        = options[:except] ? Array(options[:except]) : nil
  @key_format    = options[:key_format]
  @context       = options[:context]
  @namespace     = options[:namespace]
end

Class Attribute Details

._associationsObject

Returns the value of attribute _associations.



72
73
74
# File 'lib/active_model/serializer.rb', line 72

def _associations
  @_associations
end

._attributesObject

Returns the value of attribute _attributes.



72
73
74
# File 'lib/active_model/serializer.rb', line 72

def _attributes
  @_attributes
end

._rootObject

Returns the value of attribute _root.



72
73
74
# File 'lib/active_model/serializer.rb', line 72

def _root
  @_root
end

.key_formatObject (readonly)

Returns the value of attribute key_format.



56
57
58
# File 'lib/active_model/serializer.rb', line 56

def key_format
  @key_format
end

Instance Attribute Details

#contextObject

Returns the value of attribute context.



148
149
150
# File 'lib/active_model/serializer.rb', line 148

def context
  @context
end

#key_formatObject

Returns the value of attribute key_format.



148
149
150
# File 'lib/active_model/serializer.rb', line 148

def key_format
  @key_format
end

#metaObject

Returns the value of attribute meta.



148
149
150
# File 'lib/active_model/serializer.rb', line 148

def meta
  @meta
end

#meta_keyObject

Returns the value of attribute meta_key.



148
149
150
# File 'lib/active_model/serializer.rb', line 148

def meta_key
  @meta_key
end

#objectObject

Returns the value of attribute object.



148
149
150
# File 'lib/active_model/serializer.rb', line 148

def object
  @object
end

#polymorphicObject

Returns the value of attribute polymorphic.



148
149
150
# File 'lib/active_model/serializer.rb', line 148

def polymorphic
  @polymorphic
end

#rootObject

Returns the value of attribute root.



148
149
150
# File 'lib/active_model/serializer.rb', line 148

def root
  @root
end

#scopeObject

Returns the value of attribute scope.



148
149
150
# File 'lib/active_model/serializer.rb', line 148

def scope
  @scope
end

#serialization_optionsObject



281
282
283
# File 'lib/active_model/serializer.rb', line 281

def serialization_options
  @serialization_options || {}
end

Class Method Details

.attributes(*attrs) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/active_model/serializer.rb', line 83

def attributes(*attrs)
  attrs.each do |attr|
    striped_attr = strip_attribute attr

    @_attributes << striped_attr

    define_method striped_attr do
      object.read_attribute_for_serialization attr
    end unless method_defined?(attr)
  end
end

.embed(type, options = {}) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/active_model/serializer.rb', line 34

def embed(type, options={})
  CONFIG.embed = type
  if EMBED_IN_ROOT_OPTIONS.any? { |opt| options[opt].present? }
    CONFIG.embed_in_root = true
  end
  if options[:embed_in_root_key].present?
    CONFIG.embed_in_root_key = options[:embed_in_root_key]
  end
  ActiveSupport::Deprecation.warn <<-WARN
** Notice: embed is deprecated. **
The use of .embed method on a Serializer will be soon removed, as this should have a global scope and not a class scope.
Please use the global .setup method instead:
ActiveModel::Serializer.setup do |config|
  config.embed = :#{type}
  config.embed_in_root = #{CONFIG.embed_in_root || false}
end
  WARN
end

.format_keys(format) ⇒ Object



53
54
55
# File 'lib/active_model/serializer.rb', line 53

def format_keys(format)
  @key_format = format
end

.has_many(*attrs) ⇒ Object



99
100
101
# File 'lib/active_model/serializer.rb', line 99

def has_many(*attrs)
  associate(Association::HasMany, *attrs)
end

.has_one(*attrs) ⇒ Object



95
96
97
# File 'lib/active_model/serializer.rb', line 95

def has_one(*attrs)
  associate(Association::HasOne, *attrs)
end

.inherited(base) ⇒ Object



15
16
17
18
19
# File 'lib/active_model/serializer.rb', line 15

def inherited(base)
  base._root = _root
  base._attributes = (_attributes || []).dup
  base._associations = (_associations || {}).dup
end

.root_nameObject



76
77
78
79
80
81
# File 'lib/active_model/serializer.rb', line 76

def root_name
  if name
    root_name = name.demodulize.underscore.sub(/_serializer$/, '')
    CONFIG.plural_default_root ? root_name.pluralize : root_name
  end
end

.serializer_for(resource, options = {}) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/active_model/serializer.rb', line 58

def serializer_for(resource, options = {})
  if resource.respond_to?(:serializer_class)
    resource.serializer_class
  elsif resource.respond_to?(:to_ary)
    if Object.constants.include?(:ArraySerializer)
      ::ArraySerializer
    else
      ArraySerializer
    end
  else
    _const_get build_serializer_class(resource, options)
  end
end

.setupObject



21
22
23
24
25
# File 'lib/active_model/serializer.rb', line 21

def setup
  @mutex.synchronize do
    yield CONFIG
  end
end

Instance Method Details

#association_options_for_serializer(association) ⇒ Object



233
234
235
236
237
238
239
240
241
# File 'lib/active_model/serializer.rb', line 233

def association_options_for_serializer(association)
  prefix    = association.options[:prefix]
  namespace = association.options[:namespace] || @namespace || self.namespace

  { scope: scope }.tap do |opts|
    opts[:namespace] = namespace if namespace
    opts[:prefix]    = prefix    if prefix
  end
end

#associations(options = {}) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/active_model/serializer.rb', line 166

def associations(options={})
  associations = self.class._associations
  included_associations = filter(associations.keys)
  associations.each_with_object({}) do |(name, association), hash|
    if included_associations.include? name
      if association.embed_ids?
        ids = serialize_ids association
        if association.embed_namespace?
          hash = hash[association.embed_namespace] ||= {}
          hash[association.key] = ids
        else
          hash[association.key] = ids
        end
      elsif association.embed_objects?
        if association.embed_namespace?
          hash = hash[association.embed_namespace] ||= {}
        end
        hash[association.embedded_key] = serialize association, options
      end
    end
  end
end

#attributesObject



160
161
162
163
164
# File 'lib/active_model/serializer.rb', line 160

def attributes
  filter(self.class._attributes.dup).each_with_object({}) do |name, hash|
    hash[name] = send(name)
  end
end

#build_serializer(association) ⇒ Object



228
229
230
231
# File 'lib/active_model/serializer.rb', line 228

def build_serializer(association)
  object = send(association.name)
  association.build_serializer(object, association_options_for_serializer(association))
end

#convert_keys(hash) ⇒ Object



268
269
270
271
272
273
274
275
276
277
278
# File 'lib/active_model/serializer.rb', line 268

def convert_keys(hash)
  Hash[hash.map do |k,v|
    key = if k.is_a?(Symbol)
      format_key(k).to_sym
    else
      format_key(k)
    end

    [key ,v]
  end]
end

#embedded_in_root_associationsObject



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/active_model/serializer.rb', line 199

def embedded_in_root_associations
  associations = self.class._associations
  included_associations = filter(associations.keys)
  associations.each_with_object({}) do |(name, association), hash|
    if included_associations.include? name
      association_serializer = build_serializer(association)
      # we must do this always because even if the current association is not
      # embeded in root, it might have its own associations that are embeded in root
      hash.merge!(association_serializer.embedded_in_root_associations) do |key, oldval, newval|
        oldval.merge(newval) { |_, oldval, newval| [oldval, newval].flatten.uniq }
      end

      if association.embed_in_root?
        if association.embed_in_root_key?
          hash = hash[association.embed_in_root_key] ||= {}
        end

        serialized_data = association_serializer.serializable_object
        key = association.root_key
        if hash.has_key?(key)
          hash[key].concat(serialized_data).uniq!
        else
          hash[key] = serialized_data
        end
      end
    end
  end
end

#filter(keys) ⇒ Object



189
190
191
192
193
194
195
196
197
# File 'lib/active_model/serializer.rb', line 189

def filter(keys)
  if @only
    keys & @only
  elsif @except
    keys - @except
  else
    keys
  end
end

#format_key(key) ⇒ Object



260
261
262
263
264
265
266
# File 'lib/active_model/serializer.rb', line 260

def format_key(key)
  if key_format == :lower_camel
    key.to_s.camelize(:lower)
  else
    key
  end
end

#json_keyObject



150
151
152
153
154
155
156
157
158
# File 'lib/active_model/serializer.rb', line 150

def json_key
  key = if root == true || root.nil?
    self.class.root_name
  else
    root
  end

  key_format == :lower_camel && key.present? ? key.camelize(:lower) : key
end

#serializable_object(options = {}) ⇒ Object Also known as: serializable_hash



285
286
287
288
289
290
291
292
293
# File 'lib/active_model/serializer.rb', line 285

def serializable_object(options={})
  self.serialization_options = options
  return @wrap_in_array ? [] : nil if @object.nil?
  hash = attributes
  hash.merge! associations(options)
  hash = convert_keys(hash) if key_format.present?
  hash = { :type => type_name(@object), type_name(@object) => hash } if @polymorphic
  @wrap_in_array ? [hash] : hash
end

#serialize(association, options = {}) ⇒ Object



243
244
245
# File 'lib/active_model/serializer.rb', line 243

def serialize(association,options={})
  build_serializer(association).serializable_object(options)
end

#serialize_id(elem, association) ⇒ Object



296
297
298
299
# File 'lib/active_model/serializer.rb', line 296

def serialize_id(elem, association)
  id = elem.read_attribute_for_serialization(association.embed_key)
  association.polymorphic? ? { id: id, type: type_name(elem) } : id
end

#serialize_ids(association) ⇒ Object



247
248
249
250
251
252
253
254
# File 'lib/active_model/serializer.rb', line 247

def serialize_ids(association)
  associated_data = send(association.name)
  if associated_data.respond_to?(:to_ary)
    associated_data.map { |elem| serialize_id(elem, association) }
  else
    serialize_id(associated_data, association) if associated_data
  end
end

#type_name(elem) ⇒ Object



301
302
303
# File 'lib/active_model/serializer.rb', line 301

def type_name(elem)
  elem.class.to_s.demodulize.underscore.to_sym
end