Compare commits

...

1 Commits

Author SHA1 Message Date
46a6dac3df Fix quantity ordered scope for SQLite compatibility
Replace MySQL-specific LPAD() with SQLite's format() for zero-padded
row numbering, and skip CAST(... AS BINARY) on SQLite where string
comparisons are already binary by default.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 18:34:06 +00:00

View File

@@ -63,10 +63,16 @@ class Quantity < ApplicationRecord
scope :ordered, ->(root: nil, include_root: true) { scope :ordered, ->(root: nil, include_root: true) {
numbered = Arel::Table.new('numbered') numbered = Arel::Table.new('numbered')
path_expr = if connection.adapter_name =~ /mysql/i
numbered.cast(numbered[:child_number], 'BINARY')
else
numbered[:child_number]
end
self.model.with(numbered: numbered(:parent_id, :name)).with_recursive(arel_table.name => [ self.model.with(numbered: numbered(:parent_id, :name)).with_recursive(arel_table.name => [
numbered.project( numbered.project(
numbered[Arel.star], numbered[Arel.star],
numbered.cast(numbered[:child_number], 'BINARY').as('path') path_expr.as('path')
).where(numbered[root && include_root ? :id : :parent_id].eq(root)), ).where(numbered[root && include_root ? :id : :parent_id].eq(root)),
numbered.project( numbered.project(
numbered[Arel.star], numbered[Arel.star],
@@ -80,20 +86,25 @@ class Quantity < ApplicationRecord
# be merged with :ordered # be merged with :ordered
# https://gist.github.com/ProGM/c6df08da14708dcc28b5ca325df37ceb#extending-arel # https://gist.github.com/ProGM/c6df08da14708dcc28b5ca325df37ceb#extending-arel
scope :numbered, ->(parent_column, order_column) { scope :numbered, ->(parent_column, order_column) {
select( row_num = Arel::Nodes::NamedFunction.new('ROW_NUMBER', [])
arel_table[Arel.star], .over(Arel::Nodes::Window.new.partition(parent_column).order(order_column))
child_number = if connection.adapter_name =~ /mysql/i
Arel::Nodes::NamedFunction.new( Arel::Nodes::NamedFunction.new(
'LPAD', 'LPAD',
[ [
Arel::Nodes::NamedFunction.new('ROW_NUMBER', []) row_num,
.over(Arel::Nodes::Window.new.partition(parent_column).order(order_column)),
Arel::SelectManager.new.project( Arel::SelectManager.new.project(
Arel::Nodes::NamedFunction.new('LENGTH', [Arel.star.count]) Arel::Nodes::NamedFunction.new('LENGTH', [Arel.star.count])
).from(arel_table), ).from(arel_table),
Arel::Nodes.build_quoted('0') Arel::Nodes.build_quoted('0')
], ]
).as('child_number') )
) else
Arel::Nodes::NamedFunction.new('format', [Arel::Nodes.build_quoted('%09d'), row_num])
end
select(arel_table[Arel.star], child_number.as('child_number'))
} }
def to_s def to_s