Implement quick search logic to work with boolean search [SCI-10707][SCI-10704]

This commit is contained in:
Andrej 2024-05-16 14:00:36 +02:00
parent 112360ce9f
commit 07e7544f69
3 changed files with 54 additions and 24 deletions

View file

@ -150,13 +150,16 @@ class SearchController < ApplicationController
def object_quick_search(class_name)
search_model = class_name.to_s.camelize.constantize
search_method = search_model.method(search_model.respond_to?(:code) ? :search_by_name_and_id : :search_by_name)
search_object_classes = ["#{class_name.pluralize}.name"]
search_object_classes << search_model::PREFIXED_ID_SQL if search_model.respond_to?(:code)
search_method.call(current_user,
current_team,
params[:query],
limit: Constants::QUICK_SEARCH_LIMIT)
.order(updated_at: :desc)
search_model.search_by_search_fields_with_boolean(current_user,
current_team,
params[:query],
search_object_classes,
limit: Constants::QUICK_SEARCH_LIMIT,
fetch_latest_versions: class_name == 'protocol')
.order(updated_at: :desc)
end
def load_vars

View file

@ -36,6 +36,20 @@ module SearchableByNameModel
sql_q.limit(options[:limit] || Constants::SEARCH_LIMIT)
end
def self.search_by_search_fields_with_boolean(user, teams = [], query = nil, search_fields = [], options = {})
return if user.blank? || teams.blank?
sanitized_query = ActiveRecord::Base.sanitize_sql_like(query.to_s)
sql_q = if options[:fetch_latest_versions]
viewable_by_user(user, teams, options)
.where_attributes_like_boolean(search_fields, sanitized_query, options)
else
viewable_by_user(user, teams).where_attributes_like_boolean(search_fields, sanitized_query, options)
end
sql_q.limit(options[:limit] || Constants::SEARCH_LIMIT)
end
end
# rubocop:enable Metrics/BlockLength
end

View file

@ -178,12 +178,7 @@ class Protocol < ApplicationRecord
end || []
protocol_my_modules = if options[:options]&.dig(:in_repository).blank?
protocols = distinct.joins(:my_module)
.joins("INNER JOIN user_assignments my_module_user_assignments " \
"ON my_module_user_assignments.assignable_type = 'MyModule' " \
"AND my_module_user_assignments.assignable_id = my_modules.id")
.where(my_module_user_assignments: { user_id: user })
.where(team: teams)
protocols = viewable_by_user_my_module_protocols(user, teams)
unless include_archived
protocols = protocols.joins(my_module: { experiment: :project })
.active
@ -233,19 +228,37 @@ class Protocol < ApplicationRecord
where('protocols.id IN ((?) UNION (?) UNION (?))', original_without_versions, published_versions, new_drafts)
end
def self.viewable_by_user(user, teams)
# Team owners see all protocol templates in the team
owner_role = UserRole.find_predefined_owner_role
protocols = Protocol.where(team: teams)
.where(protocol_type: REPOSITORY_TYPES)
viewable_as_team_owner = protocols.joins("INNER JOIN user_assignments team_user_assignments " \
"ON team_user_assignments.assignable_type = 'Team' " \
"AND team_user_assignments.assignable_id = protocols.team_id")
.where(team_user_assignments: { user_id: user, user_role_id: owner_role })
.select(:id)
viewable_as_assigned = protocols.with_granted_permissions(user, ProtocolPermissions::READ).select(:id)
def self.viewable_by_user(user, teams, options = {})
if options[:fetch_latest_versions]
protocol_templates = latest_available_versions(teams)
.with_granted_permissions(user, ProtocolPermissions::READ)
.select(:id)
protocol_my_modules = viewable_by_user_my_module_protocols(user, teams).select(:id)
where('protocols.id IN ((?) UNION (?))', viewable_as_team_owner, viewable_as_assigned)
where('protocols.id IN ((?) UNION (?))', protocol_templates, protocol_my_modules)
else
# Team owners see all protocol templates in the team
owner_role = UserRole.find_predefined_owner_role
protocols = Protocol.where(team: teams)
.where(protocol_type: REPOSITORY_TYPES)
viewable_as_team_owner = protocols.joins("INNER JOIN user_assignments team_user_assignments " \
"ON team_user_assignments.assignable_type = 'Team' " \
"AND team_user_assignments.assignable_id = protocols.team_id")
.where(team_user_assignments: { user_id: user, user_role_id: owner_role })
.select(:id)
viewable_as_assigned = protocols.with_granted_permissions(user, ProtocolPermissions::READ).select(:id)
where('protocols.id IN ((?) UNION (?))', viewable_as_team_owner, viewable_as_assigned)
end
end
def self.viewable_by_user_my_module_protocols(user, teams)
distinct.joins(:my_module)
.joins("INNER JOIN user_assignments my_module_user_assignments " \
"ON my_module_user_assignments.assignable_type = 'MyModule' " \
"AND my_module_user_assignments.assignable_id = my_modules.id")
.where(my_module_user_assignments: { user_id: user })
.where(team: teams)
end
def self.filter_by_teams(teams = [])