diff --git a/app/models/quantity.rb b/app/models/quantity.rb index ed81124..3bc9d25 100644 --- a/app/models/quantity.rb +++ b/app/models/quantity.rb @@ -63,10 +63,16 @@ class Quantity < ApplicationRecord scope :ordered, ->(root: nil, include_root: true) { 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 => [ numbered.project( 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)), numbered.project( numbered[Arel.star], @@ -80,20 +86,25 @@ class Quantity < ApplicationRecord # be merged with :ordered # https://gist.github.com/ProGM/c6df08da14708dcc28b5ca325df37ceb#extending-arel scope :numbered, ->(parent_column, order_column) { - select( - arel_table[Arel.star], + row_num = Arel::Nodes::NamedFunction.new('ROW_NUMBER', []) + .over(Arel::Nodes::Window.new.partition(parent_column).order(order_column)) + + child_number = if connection.adapter_name =~ /mysql/i Arel::Nodes::NamedFunction.new( 'LPAD', [ - Arel::Nodes::NamedFunction.new('ROW_NUMBER', []) - .over(Arel::Nodes::Window.new.partition(parent_column).order(order_column)), + row_num, Arel::SelectManager.new.project( Arel::Nodes::NamedFunction.new('LENGTH', [Arel.star.count]) ).from(arel_table), 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