mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Refactor generated_relation_methods
to remove duplicated code on ClassSpecificRelation
This commit is contained in:
parent
634953af94
commit
06eabecfc0
1 changed files with 20 additions and 31 deletions
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "mutex_m"
|
||||
|
||||
module ActiveRecord
|
||||
module Delegation # :nodoc:
|
||||
module DelegateCache # :nodoc:
|
||||
|
@ -31,6 +33,10 @@ module ActiveRecord
|
|||
super
|
||||
end
|
||||
|
||||
def generate_relation_method(method)
|
||||
generated_relation_methods.generate_method(method)
|
||||
end
|
||||
|
||||
protected
|
||||
def include_relation_methods(delegate)
|
||||
superclass.include_relation_methods(delegate) unless base_class?
|
||||
|
@ -39,27 +45,32 @@ module ActiveRecord
|
|||
|
||||
private
|
||||
def generated_relation_methods
|
||||
@generated_relation_methods ||= Module.new.tap do |mod|
|
||||
mod_name = "GeneratedRelationMethods"
|
||||
const_set mod_name, mod
|
||||
private_constant mod_name
|
||||
end
|
||||
@generated_relation_methods ||= GeneratedRelationMethods.new
|
||||
end
|
||||
end
|
||||
|
||||
class GeneratedRelationMethods < Module # :nodoc:
|
||||
include Mutex_m
|
||||
|
||||
def generate_method(method)
|
||||
synchronize do
|
||||
return if method_defined?(method)
|
||||
|
||||
def generate_relation_method(method)
|
||||
if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method)
|
||||
generated_relation_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||
def #{method}(*args, &block)
|
||||
scoping { klass.#{method}(*args, &block) }
|
||||
end
|
||||
RUBY
|
||||
else
|
||||
generated_relation_methods.define_method(method) do |*args, &block|
|
||||
define_method(method) do |*args, &block|
|
||||
scoping { klass.public_send(method, *args, &block) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
private_constant :GeneratedRelationMethods
|
||||
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
|
@ -78,39 +89,17 @@ module ActiveRecord
|
|||
module ClassSpecificRelation # :nodoc:
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
@delegation_mutex = Mutex.new
|
||||
end
|
||||
|
||||
module ClassMethods # :nodoc:
|
||||
def name
|
||||
superclass.name
|
||||
end
|
||||
|
||||
def delegate_to_scoped_klass(method)
|
||||
@delegation_mutex.synchronize do
|
||||
return if method_defined?(method)
|
||||
|
||||
if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method)
|
||||
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||
def #{method}(*args, &block)
|
||||
scoping { @klass.#{method}(*args, &block) }
|
||||
end
|
||||
RUBY
|
||||
else
|
||||
define_method method do |*args, &block|
|
||||
scoping { @klass.public_send(method, *args, &block) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def method_missing(method, *args, &block)
|
||||
if @klass.respond_to?(method)
|
||||
self.class.delegate_to_scoped_klass(method)
|
||||
@klass.generate_relation_method(method)
|
||||
scoping { @klass.public_send(method, *args, &block) }
|
||||
else
|
||||
super
|
||||
|
|
Loading…
Reference in a new issue