diff --git a/app/models/custom_field/order_statements.rb b/app/models/custom_field/order_statements.rb index 9bcd73dfec2d..ccf043c36a30 100644 --- a/app/models/custom_field/order_statements.rb +++ b/app/models/custom_field/order_statements.rb @@ -209,8 +209,8 @@ def join_for_order_by_hierarchy_sql # the correct work packages for each group (see code). # # To overcome this problem the algorithms of closure_tree can be used. This method implements the same concept of - # `self_and_descendats_preorderd` from closure_tree. It uses the mathematical power operation to compute distinct - # position values from `sort_order`, the total number of descendants and the maximum dapth of the tree + # `self_and_descendants_preordered` from closure_tree. It uses the mathematical power operation to compute distinct + # position values from `sort_order`, the total number of descendants and the maximum depth of the tree # (see implementation). def hierarchy_position_sql(ancestor_id:, total_descendants:, max_depth:) <<-SQL.squish @@ -223,15 +223,15 @@ def hierarchy_position_sql(ancestor_id:, total_descendants:, max_depth:) hi.created_at, hi.updated_at, hi.custom_field_id - FROM hierarchical_items hi - INNER JOIN hierarchical_item_hierarchies hih - ON hi.id = hih.descendant_id - JOIN hierarchical_item_hierarchies anc_h - ON anc_h.descendant_id = hih.descendant_id - JOIN hierarchical_items anc - ON anc.id = anc_h.ancestor_id - JOIN hierarchical_item_hierarchies depths - ON depths.ancestor_id = #{ancestor_id} AND depths.descendant_id = anc.id + FROM hierarchical_items hi + INNER JOIN hierarchical_item_hierarchies hih + ON hi.id = hih.descendant_id + JOIN hierarchical_item_hierarchies anc_h + ON anc_h.descendant_id = hih.descendant_id + JOIN hierarchical_items anc + ON anc.id = anc_h.ancestor_id + JOIN hierarchical_item_hierarchies depths + ON depths.ancestor_id = #{ancestor_id} AND depths.descendant_id = anc.id WHERE hih.ancestor_id = #{ancestor_id} GROUP BY hi.id SQL diff --git a/spec/models/custom_field/order_statements_spec.rb b/spec/models/custom_field/order_statements_spec.rb index 79f724ee1fd8..c999399528c4 100644 --- a/spec/models/custom_field/order_statements_spec.rb +++ b/spec/models/custom_field/order_statements_spec.rb @@ -33,20 +33,47 @@ RSpec.describe CustomField::OrderStatements do # integration tests at spec/models/query/results_cf_sorting_integration_spec.rb context "when hierarchy" do + let(:service) { CustomFields::Hierarchy::HierarchicalItemService.new } + let(:item) { service.generate_root(custom_field).value! } + subject(:custom_field) { create(:hierarchy_wp_custom_field) } + before do + service.insert_item(parent: item, label: "Test") + end + describe "#order_statement" do it { expect(subject.order_statement).to eq("cf_order_#{custom_field.id}.value") } end describe "#order_join_statement" do - it do + # rubocop:disable RSpec/ExampleLength + it "must be equal" do expect(custom_field.order_join_statement).to eq( <<-SQL.squish LEFT OUTER JOIN ( - SELECT DISTINCT ON (cv.customized_id) cv.customized_id , item.label "value" + SELECT DISTINCT ON (cv.customized_id) cv.customized_id , item.position "value" , cv.value ids FROM "custom_values" cv - INNER JOIN "hierarchical_items" item ON item.id = cv.value::bigint + INNER JOIN (SELECT hi.id, + hi.parent_id, + SUM((1 + anc.sort_order) * power(2, 2 - depths.generations)) AS position, + hi.label, + hi.short, + hi.is_deleted, + hi.created_at, + hi.updated_at, + hi.custom_field_id + FROM hierarchical_items hi + INNER JOIN hierarchical_item_hierarchies hih + ON hi.id = hih.descendant_id + JOIN hierarchical_item_hierarchies anc_h + ON anc_h.descendant_id = hih.descendant_id + JOIN hierarchical_items anc + ON anc.id = anc_h.ancestor_id + JOIN hierarchical_item_hierarchies depths + ON depths.ancestor_id = #{item.id} AND depths.descendant_id = anc.id + WHERE hih.ancestor_id = #{item.id} + GROUP BY hi.id) item ON item.id = cv.value::bigint WHERE cv.customized_type = 'WorkPackage' AND cv.custom_field_id = #{custom_field.id} AND cv.value IS NOT NULL @@ -56,6 +83,7 @@ SQL ) end + # rubocop:enable RSpec/ExampleLength end end end