Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/sequel/extensions/default_order_by_id.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

# Sequel extension that adds default ORDER BY id to model queries.
#
# Hooks into fetch methods (all, each, first) to add ORDER BY id just before
# Hooks into fetch methods (all, each, first) and placeholder_literalizer_loader
# (used for optimized association loading) to add ORDER BY id just before
# execution. This ensures ordering is only added to the final query, not to
# subqueries or compound query parts.
#
Expand Down Expand Up @@ -47,6 +48,13 @@ def first(*, &)
ds.first(*, &)
end

def placeholder_literalizer_loader(&block)
super do |pl, ds|
result_ds = block.call(pl, ds)
result_ds.send(:default_order_by_id) || result_ds
end
end

private

def default_order_by_id
Expand Down
28 changes: 28 additions & 0 deletions spec/unit/lib/sequel/extensions/default_order_by_id_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,32 @@ def capture_sql(&)
end
end
end

describe 'association loading (placeholder_literalizer_loader)' do
let(:child_class) { Class.new(Sequel::Model(db[:test_default_order_join])) }

it 'adds ORDER BY id to association queries' do
child = child_class
parent_class = Class.new(Sequel::Model(db[:test_default_order_main])) do
def self.name; 'TestParent'; end # vcap_relations plugin derives reciprocal from self.name
one_to_many :children, class: child, key: :main_id
end
parent = parent_class.new
parent.values[:id] = 1
sql = capture_sql { parent.children }
expect(sql).to match(/ORDER BY .id./)
end

it 'does not override explicit association order' do
child = child_class
parent_class = Class.new(Sequel::Model(db[:test_default_order_main])) do
def self.name; 'TestParent'; end
one_to_many :children, class: child, key: :main_id, order: Sequel.desc(:id)
end
parent = parent_class.new
parent.values[:id] = 1
sql = capture_sql { parent.children }
expect(sql).to match(/ORDER BY .id. DESC/)
end
end
end
Loading