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/finder_methods.rb57
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb2
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb2
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb15
4 files changed, 28 insertions, 48 deletions
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index ff06ecbee1..98992caa0c 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -148,7 +148,7 @@ module ActiveRecord
#
# [#<Person id:4>, #<Person id:3>, #<Person id:2>]
def last(limit = nil)
- return find_last(limit) if loaded? || limit_value
+ return find_last(limit) if loaded? || has_limit_or_offset?
result = ordered_relation.limit(limit)
result = result.reverse_order!
@@ -313,7 +313,7 @@ module ActiveRecord
return false if !conditions || limit_value == 0
if eager_loading?
- relation = apply_join_dependency(construct_join_dependency(eager_loading: false))
+ relation = apply_join_dependency(eager_loading: false)
return relation.exists?(conditions)
end
@@ -358,24 +358,6 @@ module ActiveRecord
offset_value || 0
end
- def find_with_associations
- # NOTE: the JoinDependency constructed here needs to know about
- # any joins already present in `self`, so pass them in
- #
- # failing to do so means that in cases like activerecord/test/cases/associations/inner_join_association_test.rb:136
- # incorrect SQL is generated. In that case, the join dependency for
- # SpecialCategorizations is constructed without knowledge of the
- # preexisting join in joins_values to categorizations (by way of
- # the `has_many :through` for categories).
- #
- join_dependency = construct_join_dependency
-
- relation = apply_join_dependency(join_dependency)
- relation._select!(join_dependency.aliases.columns)
-
- yield relation, join_dependency
- end
-
def construct_relation_for_exists(conditions)
relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
@@ -396,17 +378,23 @@ module ActiveRecord
)
end
- def apply_join_dependency(join_dependency = construct_join_dependency)
+ def apply_join_dependency(eager_loading: true)
+ join_dependency = construct_join_dependency(eager_loading: eager_loading)
relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
- if using_limitable_reflections?(join_dependency.reflections)
- relation
- else
- if relation.limit_value
+ if eager_loading && !using_limitable_reflections?(join_dependency.reflections)
+ if has_limit_or_offset?
limited_ids = limited_ids_for(relation)
limited_ids.empty? ? relation.none! : relation.where!(primary_key => limited_ids)
end
- relation.except(:limit, :offset)
+ relation.limit_value = relation.offset_value = nil
+ end
+
+ if block_given?
+ relation._select!(join_dependency.aliases.columns)
+ yield relation, join_dependency
+ else
+ relation
end
end
@@ -532,7 +520,11 @@ module ActiveRecord
else
relation = ordered_relation
- if limit_value.nil? || index < limit_value
+ if limit_value
+ limit = [limit_value - index, limit].min
+ end
+
+ if limit > 0
relation = relation.offset(offset_index + index) unless index.zero?
relation.limit(limit).to_a
else
@@ -547,12 +539,11 @@ module ActiveRecord
else
relation = ordered_relation
- relation.to_a[-index]
- # TODO: can be made more performant on large result sets by
- # for instance, last(index)[-index] (which would require
- # refactoring the last(n) finder method to make test suite pass),
- # or by using a combination of reverse_order, limit, and offset,
- # e.g., reverse_order.offset(index-1).first
+ if equal?(relation) || has_limit_or_offset?
+ relation.records[-index]
+ else
+ relation.last(index)[-index]
+ end
end
end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb b/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
index 0255a65bfe..28c7483c95 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb
@@ -30,7 +30,7 @@ module ActiveRecord
end
def primary_key
- associated_table.association_join_keys.key
+ associated_table.association_join_primary_key
end
def convert_to_id(value)
diff --git a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
index b87b5c36dd..e8e2f2c626 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb
@@ -29,7 +29,7 @@ module ActiveRecord
end
def primary_key(value)
- associated_table.association_primary_key(base_class(value))
+ associated_table.association_join_primary_key(base_class(value))
end
def base_class(value)
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 0296101f81..009624e194 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -378,7 +378,7 @@ module ActiveRecord
if !VALID_UNSCOPING_VALUES.include?(scope)
raise ArgumentError, "Called unscope() with invalid unscoping argument ':#{scope}'. Valid arguments are :#{VALID_UNSCOPING_VALUES.to_a.join(", :")}."
end
- set_value(scope, nil)
+ set_value(scope, DEFAULT_VALUES[scope])
when Hash
scope.each do |key, target_value|
if key != :where
@@ -905,7 +905,7 @@ module ActiveRecord
protected
# Returns a relation value with a given name
def get_value(name) # :nodoc:
- @values[name] || default_value_for(name)
+ @values.fetch(name, DEFAULT_VALUES[name])
end
# Sets the relation value with the given name
@@ -1190,7 +1190,6 @@ module ActiveRecord
DEFAULT_VALUES = {
create_with: FROZEN_EMPTY_HASH,
- readonly: false,
where: Relation::WhereClause.empty,
having: Relation::WhereClause.empty,
from: Relation::FromClause.empty
@@ -1199,15 +1198,5 @@ module ActiveRecord
Relation::MULTI_VALUE_METHODS.each do |value|
DEFAULT_VALUES[value] ||= FROZEN_EMPTY_ARRAY
end
-
- Relation::SINGLE_VALUE_METHODS.each do |value|
- DEFAULT_VALUES[value] = nil if DEFAULT_VALUES[value].nil?
- end
-
- def default_value_for(name)
- DEFAULT_VALUES.fetch(name) do
- raise ArgumentError, "unknown relation value #{name.inspect}"
- end
- end
end
end