From 9c2d30c3021e31533404153b24c3eb43426861b1 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Wed, 19 Aug 2026 16:48:17 +0200 Subject: [PATCH] Implement PoC for support Boolean operators in inventory search bar [SCI-13423] --- app/models/repository_row.rb | 8 ++++-- app/services/lists/repository_rows_service.rb | 28 +++++++++++-------- app/services/repository_datatable_service.rb | 22 ++++----------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/app/models/repository_row.rb b/app/models/repository_row.rb index 022950d37e..3a6ada2261 100644 --- a/app/models/repository_row.rb +++ b/app/models/repository_row.rb @@ -172,11 +172,15 @@ def self.search(user, repository_rows.where_attributes_like_boolean(SEARCHABLE_ATTRIBUTES, query) end - def self.where_children_attributes_like(query, _options = {}) + def self.where_children_attributes_like(query, options = {}) query_clauses = [] - Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each_value do |config| + Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |data_type, config| + next if options[:data_types].present? && options[:data_types].exclude?(data_type.to_s) + query_clauses << unscoped.joins(config[:includes]).where_attributes_like(config[:field], query).to_sql end + return unscoped if query_clauses.empty? + unscoped.from("(#{query_clauses.join(' UNION ')}) AS repository_rows", :repository_rows) end diff --git a/app/services/lists/repository_rows_service.rb b/app/services/lists/repository_rows_service.rb index 3631d4cc0c..64913e796b 100644 --- a/app/services/lists/repository_rows_service.rb +++ b/app/services/lists/repository_rows_service.rb @@ -104,21 +104,25 @@ def filter_records if @params[:search].present? @records = @records.joins(:created_by) if @repository.default_search_fileds.include?('users.full_name') - data_types = @repository.repository_columns.pluck(:data_type).uniq + present_data_types = @repository.repository_columns.pluck(:data_type).uniq - filtered_records = @records.where_attributes_like(@repository.default_search_fileds, @params[:search]) + filtered_records = @records.where_attributes_like_boolean(@repository.default_search_fileds.push(:children), + @params[:search], + data_types: present_data_types) - Extends::AG_REPOSITORY_EXTRA_SEARCH_ATTR.each do |data_type, config| - next unless data_types.include?(data_type.to_s) + # Test this approach for bigger inventories, could be faster than implementation in RepositoryRow.where_children_attributes_like - filtered_records = filtered_records.or(@records.where('EXISTS (?)', - data_type.to_s.constantize - .joins(:repository_cell) - .joins(config[:includes]) - .where('repository_cells.repository_row_id = repository_rows.id') - .where_attributes_like(config[:field], @params[:search]) - .select(1))) - end + # Extends::AG_REPOSITORY_EXTRA_SEARCH_ATTR.each do |data_type, config| + # next unless data_types.include?(data_type.to_s) + + # filtered_records = filtered_records.or(@records.where('EXISTS (?)', + # data_type.to_s.constantize + # .joins(:repository_cell) + # .joins(config[:includes]) + # .where('repository_cells.repository_row_id = repository_rows.id') + # .where_attributes_like(config[:field], @params[:search]) + # .select(1))) + # end @records = filtered_records elsif @params.dig(:advanced_search, :filter_elements).present? diff --git a/app/services/repository_datatable_service.rb b/app/services/repository_datatable_service.rb index 96659bccfa..60143ca2ae 100644 --- a/app/services/repository_datatable_service.rb +++ b/app/services/repository_datatable_service.rb @@ -116,23 +116,13 @@ def fetch_rows(search_value) repository_rows = repository_rows.with_active_reminders(@repository, @user) if @params[:only_reminders] if search_value.present? - if @repository.default_search_fileds.include?('users.full_name') - repository_rows = repository_rows.joins(:created_by) - end - repository_row_matches = repository_rows.where_attributes_like(@repository.default_search_fileds, search_value) - results = repository_rows.where(id: repository_row_matches) - - data_types = @repository.repository_columns.pluck(:data_type).uniq - - Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |data_type, config| - next unless data_types.include?(data_type.to_s) - - custom_cell_matches = repository_rows.joins(config[:includes]) - .where_attributes_like(config[:field], search_value) - results = results.or(repository_rows.where(id: custom_cell_matches)) - end + repository_rows = repository_rows.joins(:created_by) if @repository.default_search_fileds.include?('users.full_name') + present_data_types = @repository.repository_columns.pluck(:data_type).uniq + repository_row_matches = repository_rows.where_attributes_like_boolean(@repository.default_search_fileds.push(:children), + search_value, + data_types: present_data_types) - repository_rows = results + repository_rows = repository_rows.where(id: repository_row_matches) end repository_rows = repository_rows.where(id: advanced_search(repository_rows)) if @params[:advanced_search].present?