aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2019-02-28 01:32:57 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-02-28 01:32:57 +0900
commit06eabecfc0c5f9022b74061fde1bb30f5afb4945 (patch)
treeb08a2bbc5fcc0d3e69ed9a1e90f882edc40df72c /activerecord
parent634953af94f8677f9fd3b07b9560139f50d29467 (diff)
downloadrails-06eabecfc0c5f9022b74061fde1bb30f5afb4945.tar.gz
rails-06eabecfc0c5f9022b74061fde1bb30f5afb4945.tar.bz2
rails-06eabecfc0c5f9022b74061fde1bb30f5afb4945.zip
Refactor `generated_relation_methods` to remove duplicated code on `ClassSpecificRelation`
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/relation/delegation.rb51
1 files changed, 20 insertions, 31 deletions
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index f7c3b3783f..7a53a9d1c7 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -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