class Octoball::RelationProxy

Constants

ENUM_METHODS
ENUM_WITH_BLOCK_METHODS

Attributes

current_shard[R]

Public Class Methods

new(rel, shard) click to toggle source
# File lib/octoball/relation_proxy.rb, line 7
def initialize(rel, shard)
  @rel = rel
  self.current_shard = shard
end

Public Instance Methods

==(obj) click to toggle source
# File lib/octoball/relation_proxy.rb, line 87
def ==(obj)
  return false if obj.respond_to?(:current_shard) && obj.current_shard != @current_shard
  return @rel == obj unless @current_shard
  ::ActiveRecord::Base.connected_to(shard: @current_shard, role: ::Octoball.current_role) { @rel == obj }
end
===(obj) click to toggle source
# File lib/octoball/relation_proxy.rb, line 93
def ===(obj)
  return false if obj.respond_to?(:current_shard) && obj.current_shard != @current_shard
  return @rel === obj unless @current_shard
  ::ActiveRecord::Base.connected_to(shard: @current_shard, role: ::Octoball.current_role) { @rel === obj }
end
ar_relation() click to toggle source
# File lib/octoball/relation_proxy.rb, line 22
def ar_relation
  @rel
end
current_shard=(shard) click to toggle source
# File lib/octoball/relation_proxy.rb, line 12
def current_shard=(shard)
  @current_shard = shard
  @rel.current_shard = shard unless @rel.is_a?(::Enumerator)
end
inspect() click to toggle source
# File lib/octoball/relation_proxy.rb, line 82
def inspect
  return @rel.inspect unless @current_shard
  ::ActiveRecord::Base.connected_to(shard: @current_shard, role: ::Octoball.current_role) { @rel.inspect }
end
method_missing(method, *args, &block) click to toggle source
# File lib/octoball/relation_proxy.rb, line 36
    def method_missing(method, *args, &block)
      # raise NoMethodError unless the method is defined in @rel
      return @rel.public_send(method, *args, &block) unless @rel.respond_to?(method)

      preamble = <<-EOS
        def #{method}(*margs, &mblock)
          return @rel.#{method}(*margs, &mblock) unless @current_shard
      EOS
      postamble = <<-EOS
          return ret unless ret.is_a?(::ActiveRecord::Relation) || ret.is_a?(::ActiveRecord::QueryMethods::WhereChain) || ret.is_a?(::Enumerator)
          ::Octoball::RelationProxy.new(ret, @current_shard)
        end
        ruby2_keywords(:#{method}) if respond_to?(:ruby2_keywords, true)
      EOS
      connected_to = '::ActiveRecord::Base.connected_to(role: ::Octoball.current_role, shard: @current_shard)'

      if ENUM_METHODS.include?(method)
        ::Octoball::RelationProxy.class_eval <<-EOS, __FILE__, __LINE__ - 1
          #{preamble}
          ret = #{connected_to} { @rel.to_a }.#{method}(*margs, &mblock)
          #{postamble}
        EOS
      elsif ENUM_WITH_BLOCK_METHODS.include?(method)
        ::Octoball::RelationProxy.class_eval <<-EOS, __FILE__, __LINE__ - 1
          #{preamble}
          ret = nil
          if mblock
            ret = #{connected_to} { @rel.to_a }.#{method}(*margs, &mblock)
          else
            #{connected_to} { ret = @rel.#{method}(*margs, &mblock); nil } # return nil to avoid loading relation
          end
          #{postamble}
        EOS
      else
        ::Octoball::RelationProxy.class_eval <<-EOS, __FILE__, __LINE__ - 1
          #{preamble}
          ret = nil
          #{connected_to} { ret = @rel.#{method}(*margs, &mblock); nil } # return nil to avoid loading relation
          #{postamble}
        EOS
      end

      public_send(method, *args, &block)
    end
respond_to?(method, include_all = false) click to toggle source
# File lib/octoball/relation_proxy.rb, line 26
def respond_to?(method, include_all = false)
  return true if [:ar_relation, :current_shard, :current_shard=, :using].include?(method)
  @rel.respond_to?(method, include_all)
end
using(shard) click to toggle source
# File lib/octoball/relation_proxy.rb, line 17
def using(shard)
  self.current_shard = shard
  self
end