forked from fixin.me/fixin.me
Unlimited depth hierarchy ordering
This commit is contained in:
parent
3788f1a749
commit
0d8e7c6c0e
@ -12,14 +12,44 @@ class Quantity < ApplicationRecord
|
|||||||
|
|
||||||
scope :defaults, ->{ where(user: nil) }
|
scope :defaults, ->{ where(user: nil) }
|
||||||
scope :ordered, ->{
|
scope :ordered, ->{
|
||||||
left_outer_joins(:parent).order(ordering)
|
cte = Arel::Table.new('cte')
|
||||||
|
numbered = Arel::Table.new('numbered')
|
||||||
|
Quantity.with(numbered: numbered(:parent_id, :name)).with_recursive(
|
||||||
|
cte:
|
||||||
|
[
|
||||||
|
Arel::SelectManager.new.project(
|
||||||
|
numbered[Arel.star],
|
||||||
|
numbered.cast(numbered[:child_number], 'BINARY').as('path')
|
||||||
|
).from(numbered).where(numbered[:parent_id].eq(nil)),
|
||||||
|
Arel::SelectManager.new.project(
|
||||||
|
numbered[Arel.star],
|
||||||
|
cte[:path].concat(numbered[:child_number])
|
||||||
|
).from(numbered).join(cte).on(numbered[:parent_id].eq(cte[:id]))
|
||||||
|
]
|
||||||
|
).select(cte[Arel.star]).from(cte).order(cte[:path])
|
||||||
}
|
}
|
||||||
|
|
||||||
def self.ordering
|
scope :numbered, ->(parent_column, order_column){
|
||||||
[arel_table.coalesce(Arel::Table.new(:parents_quantities)[:name], arel_table[:name]),
|
select(
|
||||||
arel_table[:parent_id].not_eq(nil),
|
arel_table[Arel.star],
|
||||||
:name]
|
Arel::Nodes::NamedFunction.new(
|
||||||
end
|
'LPAD',
|
||||||
|
[
|
||||||
|
Arel::Nodes::NamedFunction.new(
|
||||||
|
'ROW_NUMBER', []
|
||||||
|
).over(
|
||||||
|
Arel::Nodes::Window.new.partition(parent_column).order(order_column)
|
||||||
|
),
|
||||||
|
Arel::SelectManager.new.project(
|
||||||
|
Arel::Nodes::NamedFunction.new(
|
||||||
|
'LENGTH', [Arel::Nodes::NamedFunction.new('COUNT', [Arel.star])]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Arel::Nodes.build_quoted('0')
|
||||||
|
],
|
||||||
|
).as('child_number')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
name
|
name
|
||||||
|
Loading…
x
Reference in New Issue
Block a user