Skip to content

Commit

Permalink
Merge pull request #4282 from edgecase/order_after_reorder
Browse files Browse the repository at this point in the history
correctly handle order calls after a reorder
  • Loading branch information
tenderlove committed Jan 4, 2012
2 parents 5708648 + efbb85c commit 34551bf
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 9 deletions.
2 changes: 1 addition & 1 deletion activerecord/lib/active_record/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Relation
JoinOperation = Struct.new(:relation, :join_class, :on)
ASSOCIATION_METHODS = [:includes, :eager_load, :preload]
MULTI_VALUE_METHODS = [:select, :group, :order, :joins, :where, :having, :bind]
SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reorder, :reverse_order, :uniq]
SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reordering, :reverse_order, :uniq]

include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation

Expand Down
4 changes: 2 additions & 2 deletions activerecord/lib/active_record/relation/finder_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def first!
def last(*args)
if args.any?
if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash))
if order_values.empty? && reorder_value.nil?
if order_values.empty?
order("#{primary_key} DESC").limit(*args).reverse
else
to_a.last(*args)
Expand Down Expand Up @@ -249,7 +249,7 @@ def apply_join_dependency(relation, join_dependency)
end

def construct_limited_ids_condition(relation)
orders = (relation.reorder_value || relation.order_values).map { |val| val.presence }.compact
orders = relation.order_values.map { |val| val.presence }.compact
values = @klass.connection.distinct("#{@klass.connection.quote_table_name table_name}.#{primary_key}", orders)

relation = relation.dup
Expand Down
7 changes: 4 additions & 3 deletions activerecord/lib/active_record/relation/query_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module QueryMethods
:select_values, :group_values, :order_values, :joins_values,
:where_values, :having_values, :bind_values,
:limit_value, :offset_value, :lock_value, :readonly_value, :create_with_value,
:from_value, :reorder_value, :reverse_order_value,
:from_value, :reordering_value, :reverse_order_value,
:uniq_value

def includes(*args)
Expand Down Expand Up @@ -97,7 +97,8 @@ def reorder(*args)
return self if args.blank?

relation = clone
relation.reorder_value = args.flatten
relation.reordering_value = true
relation.order_values = args.flatten
relation
end

Expand Down Expand Up @@ -263,7 +264,7 @@ def build_arel

arel.group(*@group_values.uniq.reject{|g| g.blank?}) unless @group_values.empty?

order = @reorder_value ? @reorder_value : @order_values
order = @order_values
order = reverse_sql_order(order) if @reverse_order_value
arel.order(*order.uniq.reject{|o| o.blank?}) unless order.empty?

Expand Down
13 changes: 11 additions & 2 deletions activerecord/lib/active_record/relation/spawn_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def merge(r)
end
end

(Relation::MULTI_VALUE_METHODS - [:joins, :where]).each do |method|
(Relation::MULTI_VALUE_METHODS - [:joins, :where, :order]).each do |method|
value = r.send(:"#{method}_values")
merged_relation.send(:"#{method}_values=", merged_relation.send(:"#{method}_values") + value) if value.present?
end
Expand All @@ -48,7 +48,7 @@ def merge(r)

merged_relation.where_values = merged_wheres

(Relation::SINGLE_VALUE_METHODS - [:lock, :create_with]).each do |method|
(Relation::SINGLE_VALUE_METHODS - [:lock, :create_with, :reordering]).each do |method|
value = r.send(:"#{method}_value")
merged_relation.send(:"#{method}_value=", value) unless value.nil?
end
Expand All @@ -57,6 +57,15 @@ def merge(r)

merged_relation = merged_relation.create_with(r.create_with_value) unless r.create_with_value.empty?

if (r.reordering_value)
# override any order specified in the original relation
merged_relation.reordering_value = true
merged_relation.order_values = r.order_values
else
# merge in order_values from r
merged_relation.order_values += r.order_values
end

# Apply scope extension modules
merged_relation.send :apply_modules, r.extensions

Expand Down
6 changes: 6 additions & 0 deletions activerecord/test/cases/relation_scoping_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,12 @@ def test_reorder_overrides_default_scope_order
assert_equal expected, received
end

def test_order_after_reorder_combines_orders
expected = Developer.order('name DESC, id DESC').collect { |dev| [dev.name, dev.id] }
received = Developer.order('name ASC').reorder('name DESC').order('id DESC').collect { |dev| [dev.name, dev.id] }
assert_equal expected, received
end

def test_nested_exclusive_scope
expected = Developer.find(:all, :limit => 100).collect { |dev| dev.salary }
received = DeveloperOrderedBySalary.send(:with_exclusive_scope, :find => { :limit => 100 }) do
Expand Down
2 changes: 1 addition & 1 deletion activerecord/test/cases/relation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def test_construction
end

def test_single_values
assert_equal [:limit, :offset, :lock, :readonly, :from, :reorder, :reverse_order, :uniq].map(&:to_s).sort,
assert_equal [:limit, :offset, :lock, :readonly, :from, :reordering, :reverse_order, :uniq].map(&:to_s).sort,
Relation::SINGLE_VALUE_METHODS.map(&:to_s).sort
end

Expand Down

0 comments on commit 34551bf

Please sign in to comment.