Class: Miscellany::ArbitraryPrefetch::ScopeResolver

Inherits:
BasicObject
Defined in:
lib/miscellany/active_record/arbitrary_prefetch.rb

Overview

Evaluates a prefetch scope block such as ->{ comments.where(favorite: true) }. Association names answer with an unscoped Relation on the association's target class and record which association the prefetch is based off of. Everything else falls through to the block's original self, so surrounding helper methods still work.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, fallback) ⇒ ScopeResolver

Returns a new instance of ScopeResolver.



77
78
79
80
81
# File 'lib/miscellany/active_record/arbitrary_prefetch.rb', line 77

def initialize(model, fallback)
  @model = model
  @fallback = fallback
  @source_key = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/miscellany/active_record/arbitrary_prefetch.rb', line 87

def method_missing(name, *args, &block)
  reflection = @model.reflections[name.to_s]

  if reflection.nil?
    unless @fallback
      ::Kernel.raise ::NameError, "undefined local variable or method `#{name}' for prefetch scope on #{@model}"
    end
    return @fallback.__send__(name, *args, &block)
  end

  if @source_key && @source_key != name.to_sym
    ::Kernel.raise ::ArgumentError,
      "prefetch scope references two associations (#{@source_key} and #{name}); it may only build off of one"
  end

  @source_key = name.to_sym
  reflection.klass.all
end

Instance Attribute Details

#source_keyObject (readonly)

Returns the value of attribute source_key.



75
76
77
# File 'lib/miscellany/active_record/arbitrary_prefetch.rb', line 75

def source_key
  @source_key
end

Instance Method Details

#__evaluate__(block) ⇒ Object



83
84
85
# File 'lib/miscellany/active_record/arbitrary_prefetch.rb', line 83

def __evaluate__(block)
  [instance_exec(&block), @source_key]
end