aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/relation')
-rw-r--r--activerecord/lib/active_record/relation/calculations.rb4
-rw-r--r--activerecord/lib/active_record/relation/delegation.rb24
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb6
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb10
4 files changed, 29 insertions, 15 deletions
diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb
index a7d2f4bd24..df27318678 100644
--- a/activerecord/lib/active_record/relation/calculations.rb
+++ b/activerecord/lib/active_record/relation/calculations.rb
@@ -165,7 +165,9 @@ module ActiveRecord
if has_include?(column_names.first)
construct_relation_for_association_calculations.pluck(*column_names)
else
- result = klass.connection.select_all(select(column_names).arel, nil, bind_values)
+ relation = spawn
+ relation.select_values = column_names
+ result = klass.connection.select_all(relation.arel, nil, bind_values)
columns = result.columns.map do |key|
klass.column_types.fetch(key) {
result.column_types.fetch(key) {
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index ab8b36c8ab..dbfa92bbbd 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -1,3 +1,4 @@
+require 'thread'
module ActiveRecord
module Delegation # :nodoc:
@@ -6,6 +7,8 @@ module ActiveRecord
delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
:connection, :columns_hash, :auto_explain_threshold_in_seconds, :to => :klass
+ @@delegation_mutex = Mutex.new
+
def self.delegate_to_scoped_klass(method)
if method.to_s =~ /\A[a-zA-Z_]\w*[!?]?\z/
module_eval <<-RUBY, __FILE__, __LINE__ + 1
@@ -32,13 +35,28 @@ module ActiveRecord
def method_missing(method, *args, &block)
if @klass.respond_to?(method)
- ::ActiveRecord::Delegation.delegate_to_scoped_klass(method)
+ @@delegation_mutex.synchronize do
+ unless ::ActiveRecord::Delegation.method_defined?(method)
+ ::ActiveRecord::Delegation.delegate_to_scoped_klass(method)
+ end
+ end
+
scoping { @klass.send(method, *args, &block) }
elsif Array.method_defined?(method)
- ::ActiveRecord::Delegation.delegate method, :to => :to_a
+ @@delegation_mutex.synchronize do
+ unless ::ActiveRecord::Delegation.method_defined?(method)
+ ::ActiveRecord::Delegation.delegate method, :to => :to_a
+ end
+ end
+
to_a.send(method, *args, &block)
elsif arel.respond_to?(method)
- ::ActiveRecord::Delegation.delegate method, :to => :arel
+ @@delegation_mutex.synchronize do
+ unless ::ActiveRecord::Delegation.method_defined?(method)
+ ::ActiveRecord::Delegation.delegate method, :to => :arel
+ end
+ end
+
arel.send(method, *args, &block)
else
super
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 99c2f45bc8..af67b2ba6c 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/hash/indifferent_access'
-
module ActiveRecord
module FinderMethods
# Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
@@ -225,7 +223,7 @@ module ActiveRecord
def construct_limited_ids_condition(relation)
orders = relation.order_values.map { |val| val.presence }.compact
- values = @klass.connection.distinct("#{@klass.connection.quote_table_name table_name}.#{primary_key}", orders)
+ values = @klass.connection.distinct("#{quoted_table_name}.#{primary_key}", orders)
relation = relation.dup
@@ -234,8 +232,6 @@ module ActiveRecord
end
def find_with_ids(*ids)
- return to_a.find { |*block_args| yield(*block_args) } if block_given?
-
expects_array = ids.first.kind_of?(Array)
return ids.first if expects_array && ids.first.empty?
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 4fdc296c7e..0817bb6d81 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -218,7 +218,6 @@ module ActiveRecord
# Like #order, but modifies relation in place.
def order!(*args)
args.flatten!
-
validate_order_args args
references = args.reject { |arg| Arel::Node === arg }
@@ -245,7 +244,6 @@ module ActiveRecord
# Like #reorder, but modifies relation in place.
def reorder!(*args)
args.flatten!
-
validate_order_args args
self.reordering_value = true
@@ -796,7 +794,7 @@ module ActiveRecord
def reverse_sql_order(order_query)
order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty?
- order_query.map do |o|
+ order_query.flat_map do |o|
case o
when Arel::Nodes::Ordering
o.reverse
@@ -814,7 +812,7 @@ module ActiveRecord
else
o
end
- end.flatten
+ end
end
def array_of_strings?(o)
@@ -825,7 +823,7 @@ module ActiveRecord
orders = order_values
orders = reverse_sql_order(orders) if reverse_order_value
- orders = orders.uniq.reject(&:blank?).map do |order|
+ orders = orders.uniq.reject(&:blank?).flat_map do |order|
case order
when Symbol
table[order].asc
@@ -834,7 +832,7 @@ module ActiveRecord
else
order
end
- end.flatten
+ end
arel.order(*orders) unless orders.empty?
end