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) ⇒ 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) ⇒ 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 |
# File 'lib/octoball/relation_proxy.rb', line 36 def method_missing(method, ...) # raise NoMethodError unless the method is defined in @rel return @rel.public_send(method, ...) unless @rel.respond_to?(method) preamble = <<-EOS def #{method}(*, **, &mblock) return @rel.#{method}(*, **, &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 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}(*, **, &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}(*, **, &mblock) else #{connected_to} { ret = @rel.#{method}(*, **, &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}(*, **, &mblock); nil } # return nil to avoid loading relation #{postamble} EOS end public_send(method, ...) 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
85 86 87 88 89 |
# File 'lib/octoball/relation_proxy.rb', line 85 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
91 92 93 94 95 |
# File 'lib/octoball/relation_proxy.rb', line 91 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
80 81 82 83 |
# File 'lib/octoball/relation_proxy.rb', line 80 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 |