Class: Octoball::RelationProxy
- Inherits:
- BasicObject
- Defined in:
- lib/octoball/relation_proxy.rb
Constant Summary collapse
- ENUM_METHODS =
(::Enumerable.instance_methods - ::Object.instance_methods).reject do |m| ::ActiveRecord::Relation.instance_method(m).source_location rescue nil end + [:each, :map, :index_by]
- ENUM_WITH_BLOCK_METHODS =
[:find, :select, :none?, :any?, :one?, :many?, :sum]
Instance Attribute Summary collapse
-
#current_shard ⇒ Object
Returns the value of attribute current_shard.
Instance Method Summary collapse
- #==(obj) ⇒ Object
- #===(obj) ⇒ Object
- #ar_relation ⇒ Object
-
#initialize(rel, shard) ⇒ RelationProxy
constructor
A new instance of RelationProxy.
- #inspect ⇒ Object
- #method_missing(method, *args, &block) ⇒ Object
- #respond_to?(method, include_all = false) ⇒ Boolean
- #using(shard) ⇒ Object
Constructor Details
#initialize(rel, shard) ⇒ RelationProxy
Returns a new instance of RelationProxy.
7 8 9 10 |
# File 'lib/octoball/relation_proxy.rb', line 7 def initialize(rel, shard) @rel = rel self.current_shard = shard end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# 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 |
Instance Attribute Details
#current_shard ⇒ Object
Returns the value of attribute current_shard.
5 6 7 |
# File 'lib/octoball/relation_proxy.rb', line 5 def current_shard @current_shard end |
Instance Method Details
#==(obj) ⇒ Object
87 88 89 90 91 |
# 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) ⇒ Object
93 94 95 96 97 |
# 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 ⇒ Object
22 23 24 |
# File 'lib/octoball/relation_proxy.rb', line 22 def ar_relation @rel end |
#inspect ⇒ Object
82 83 84 85 |
# 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 |
#respond_to?(method, include_all = false) ⇒ Boolean
26 27 28 29 |
# 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) ⇒ Object
17 18 19 20 |
# File 'lib/octoball/relation_proxy.rb', line 17 def using(shard) self.current_shard = shard self end |