Class: ActiveModel::Serializer::Reflection

Inherits:
Field
  • Object
show all
Defined in:
lib/active_model/serializer/reflection.rb

Overview

Holds all the meta-data about an association as it was specified in the ActiveModel::Serializer class.

Specifically, the association 'comments' is evaluated two different ways:
1) as 'comments' and named 'comments'.
2) as 'object.comments.last(1)' and named 'last_comments'.

PostSerializer._reflections #=>
  # [
  #   HasOneReflection.new(:author, serializer: AuthorSerializer),
  #   HasManyReflection.new(:comments)
  #   HasManyReflection.new(:comments, { key: :last_comments }, #<Block>)
  #   HasManyReflection.new(:secret_meta_data, { if: :is_admin? })
  # ]

So you can inspect reflections in your Adapters.

Examples:

class PostSerializer < ActiveModel::Serializer
  has_one :author, serializer: AuthorSerializer
  has_many :comments
  has_many :comments, key: :last_comments do
    object.comments.last(1)
  end
  has_many :secret_meta_data, if: :is_admin?

  def is_admin?
    current_user.admin?
  end
end

Direct Known Subclasses

CollectionReflection, SingularReflection

Instance Attribute Summary

Attributes inherited from Field

#block, #name, #options

Instance Method Summary (collapse)

Constructor Details

- (Reflection) initialize

Returns a new instance of Reflection



37
38
39
40
41
42
# File 'lib/active_model/serializer/reflection.rb', line 37

def initialize(*)
  super
  @_links = {}
  @_include_data = true
  @_meta = nil
end

Instance Method Details

- (Object) build_association(subject, parent_serializer_options)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Build association. This method is used internally to build serializer's association by its reflection.

Examples:

# Given the following serializer defined:
class PostSerializer < ActiveModel::Serializer
  has_many :comments, serializer: CommentSummarySerializer
end

# Then you instantiate your serializer
post_serializer = PostSerializer.new(post, foo: 'bar') #
# to build association for comments you need to get reflection
comments_reflection = PostSerializer._reflections.detect { |r| r.name == :comments }
# and #build_association
comments_reflection.build_association(post_serializer, foo: 'bar')

Parameters:

  • subject (Serializer)

    is a parent serializer for given association

  • parent_serializer_options (Hash{Symbol => Object})


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/active_model/serializer/reflection.rb', line 109

def build_association(subject, parent_serializer_options)
  association_value = value(subject)
  reflection_options = options.dup
  serializer_class = subject.class.serializer_for(association_value, reflection_options)
  reflection_options[:include_data] = @_include_data

  if serializer_class
    begin
      serializer = serializer_class.new(
        association_value,
        serializer_options(subject, parent_serializer_options, reflection_options)
      )
    rescue ActiveModel::Serializer::CollectionSerializer::NoSerializerError
      reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
    end
  elsif !association_value.nil? && !association_value.instance_of?(Object)
    reflection_options[:virtual_value] = association_value
  end

  Association.new(name, serializer, reflection_options, @_links, @_meta)
end

- (Object) include_data(value = true)



54
55
56
57
# File 'lib/active_model/serializer/reflection.rb', line 54

def include_data(value = true)
  @_include_data = value
  :nil
end


44
45
46
47
# File 'lib/active_model/serializer/reflection.rb', line 44

def link(name, value = nil, &block)
  @_links[name] = block || value
  :nil
end

- (Object) meta(value = nil, &block)



49
50
51
52
# File 'lib/active_model/serializer/reflection.rb', line 49

def meta(value = nil, &block)
  @_meta = block || value
  :nil
end

- (:nil, associated resource or resource collection) value(serializer) {|ActiveModel::Serializer| ... }

Examples:

has_one :blog do |serializer|
  serializer.cached_blog
end

def cached_blog
  cache_store.fetch("cached_blog:#{object.updated_at}") do
    Blog.find(object.blog_id)
  end
end

Parameters:

Yields:

Returns:

  • (:nil, associated resource or resource collection)


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/active_model/serializer/reflection.rb', line 72

def value(serializer)
  @object = serializer.object
  @scope = serializer.scope

  if block
    block_value = instance_exec(serializer, &block)
    if block_value != :nil
      block_value
    elsif @_include_data
      serializer.read_attribute_for_serialization(name)
    end
  else
    serializer.read_attribute_for_serialization(name)
  end
end