Module: AmsLazyRelationships::Core::LazyDigMethod

Defined in:
lib/ams_lazy_relationships/core/lazy_dig_method.rb

Overview

Provides ‘lazy_dig` as an instance method for serializers, in order to make possible to dig relationships in depth just like `Hash#dig` do, keeping the laziness and N+1-free evaluation.

Instance Method Summary collapse

Instance Method Details

#lazy_dig(*relation_names) ⇒ ActiveRecord::Base, ...

Returns ActiveRecord objects found by digging through the sequence of nested relationships. Singular or plural nature of returned value depends from the singular/plural nature of the chain of relation_names.

Examples:

class AuthorSerializer < BaseSerializer
  lazy_belongs_to :address
  lazy_has_many :rewards
end

class BlogPostSerializer < BaseSerializer
  lazy_belongs_to :author

  attribute :author_address do
    # returns single AR object or nil
    lazy_dig(:author, :address)&.full_address
  end

  attribute :author_rewards do
    # returns an array of AR objects
    lazy_dig(:author, :rewards).map(&:description)
  end
end

Parameters:

  • relation_names (Array<Symbol>)

    the sequence of relation names to dig through.

Returns:

  • (ActiveRecord::Base, Array<ActiveRecord::Base>, nil)

    ActiveRecord objects found by digging through the sequence of nested relationships. Singular or plural nature of returned value depends from the singular/plural nature of the chain of relation_names.



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

def lazy_dig(*relation_names)
  relationships = {
    multiple: false,
    data: [{
      serializer: self.class,
      object: object
    }]
  }

  relation_names.each do |relation_name|
    lazy_dig_relationship!(relation_name, relationships)
  end

  objects = relationships[:data].map { |r| r[:object] }

  relationships[:multiple] ? objects : objects.first
end