Project

General

Profile

« Previous | Next » 

Revision 72209166

Added by Adam Ruzicka about 4 years ago

Fixes #29447 - Build more efficient taxonomy search for filters

If a filter supported taxonomy filtering and the role had many taxonomies
assigned then the resulting search query consisted of many id comparisons joined
together with ORs. This commit generates more efficient query by performing the
search as id IN (...).

View differences:

app/models/filter.rb
end
def build_taxonomy_search_string(name)
relation = name.pluralize
taxes = send(relation).empty? ? [] : send(relation).map { |t| "#{name}_id = #{t.id}" }
taxes = taxes.join(' or ')
parenthesize(taxes)
relation = send(name.pluralize).pluck(:id)
return '' if relation.empty?
parenthesize("#{name}_id ^ (#{relation.join(',')})")
end
def nilify_empty_searches
test/models/filter_test.rb
f = FactoryBot.build_stubbed(:filter, :search => '', :unlimited => '1', :organization_ids => [@organization.id])
assert f.valid?
assert f.limited?
assert_include f.taxonomy_search, "(organization_id = #{@organization.id})"
assert_include f.taxonomy_search, "(organization_id ^ (#{@organization.id}))"
assert_not_include f.taxonomy_search, ' and '
assert_not_include f.taxonomy_search, ' or '
end
......
f = FactoryBot.build_stubbed(:filter, :search => '', :unlimited => '1', :location_ids => [@location.id])
assert f.valid?
assert f.limited?
assert_include f.taxonomy_search, "(location_id = #{@location.id})"
assert_include f.taxonomy_search, "(location_id ^ (#{@location.id}))"
end
test "filter with location set is always limited before validation" do
......
:organization_ids => [@organization.id, @organization1.id], :location_ids => [@location.id])
assert f.valid?
assert f.limited?
assert_include f.taxonomy_search, "(location_id = #{@location.id})"
assert_include f.taxonomy_search, "organization_id = #{@organization.id}"
assert_include f.taxonomy_search, "organization_id = #{@organization1.id}"
assert_equal "(organization_id ^ (#{@organization.id},#{@organization1.id})) and (location_id ^ (#{@location.id}))", f.taxonomy_search
end
test "removing all organizations and locations from filter nilify taxonomy search" do
......
f.role = FactoryBot.build(:role, :organizations => [FactoryBot.build(:organization)])
f.save # we need ids
f.enforce_inherited_taxonomies
assert_equal "(organization_id = #{f.organizations.first.id})", f.taxonomy_search
assert_equal "(organization_id ^ (#{f.organizations.first.id}))", f.taxonomy_search
end
end

Also available in: Unified diff