From 77da6476e29317ece5c7e57706b47d73cdf6903b Mon Sep 17 00:00:00 2001 From: navaneethkp36 Date: Tue, 13 Jan 2026 21:32:14 +0530 Subject: [PATCH 1/2] Include nil values in scope filtering --- lib/closure_tree/support.rb | 4 ++-- test/closure_tree/scope_test.rb | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/closure_tree/support.rb b/lib/closure_tree/support.rb index 4405b15..30e3b21 100644 --- a/lib/closure_tree/support.rb +++ b/lib/closure_tree/support.rb @@ -238,12 +238,12 @@ def scope_values_from_instance(instance) case scope_option when Symbol value = instance.read_attribute(scope_option) - scope_hash[scope_option] = value unless value.nil? + scope_hash[scope_option] = value when Array scope_option.each do |item| if item.is_a?(Symbol) value = instance.read_attribute(item) - scope_hash[item] = value unless value.nil? + scope_hash[item] = value end end end diff --git a/test/closure_tree/scope_test.rb b/test/closure_tree/scope_test.rb index 8101f61..eedde85 100644 --- a/test/closure_tree/scope_test.rb +++ b/test/closure_tree/scope_test.rb @@ -175,5 +175,36 @@ def test_scope_columns_method assert_equal [:user_id], ScopedItem._ct.scope_columns assert_equal [:user_id, :group_id], MultiScopedItem._ct.scope_columns end -end + def test_scope_values_from_instance_with_nil_value_symbol_scope + instance = ScopedItem.new(user_id: nil) + scope_values = instance._ct.scope_values_from_instance(instance) + assert_equal({ user_id: nil }, scope_values) + end + + def test_scope_values_from_instance_with_nil_value_array_scope + instance = MultiScopedItem.new(user_id: nil, group_id: nil) + scope_values = instance._ct.scope_values_from_instance(instance) + assert_equal({ user_id: nil, group_id: nil }, scope_values) + end + + def test_ordering_with_nil_scope_values_symbol_scope + root1 = ScopedItem.create!(name: 'root1', user_id: nil) + root2 = ScopedItem.create!(name: 'root2', user_id: 1) + root3 = ScopedItem.create!(name: 'root3', user_id: nil) + + assert_equal 0, root1.order_value + assert_equal 1, root3.order_value + assert_equal 0, root2.order_value + end + + def test_ordering_with_nil_scope_values_array_scope + root1 = MultiScopedItem.create!(name: 'root1', user_id: nil, group_id: nil) + root2 = MultiScopedItem.create!(name: 'root2', user_id: 1, group_id: 1) + root3 = MultiScopedItem.create!(name: 'root3', user_id: nil, group_id: nil) + + assert_equal 0, root1.order_value + assert_equal 1, root3.order_value + assert_equal 0, root2.order_value + end +end From 3d71ad02ea4fd2affff1536722ae2b64f249d823 Mon Sep 17 00:00:00 2001 From: navaneethkp36 Date: Tue, 13 Jan 2026 22:43:22 +0530 Subject: [PATCH 2/2] Add separate tests for each DB type --- test/closure_tree/scope_test.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/closure_tree/scope_test.rb b/test/closure_tree/scope_test.rb index eedde85..56dd4a0 100644 --- a/test/closure_tree/scope_test.rb +++ b/test/closure_tree/scope_test.rb @@ -207,4 +207,31 @@ def test_ordering_with_nil_scope_values_array_scope assert_equal 1, root3.order_value assert_equal 0, root2.order_value end + + def test_build_scope_where_clause_with_nil_value_pg + support = ScopedItem._ct + scope_conditions = { user_id: nil, group_id: 789 } + clause = support.build_scope_where_clause(scope_conditions) + + assert_includes clause, 'IS NULL' + assert_includes clause, '789' + end + + def test_build_scope_where_clause_with_nil_value_mysql + support = MysqlTag._ct + scope_conditions = { user_id: nil, group_id: 123 } + clause = support.build_scope_where_clause(scope_conditions) + + assert_includes clause, 'IS NULL' + assert_includes clause, '123' + end + + def test_build_scope_where_clause_with_nil_value_sqlite + support = MemoryTag._ct + scope_conditions = { user_id: nil, group_id: 456 } + clause = support.build_scope_where_clause(scope_conditions) + + assert_includes clause, 'IS NULL' + assert_includes clause, '456' + end end