Optimize use of permission checking scopes in search queries [SCI-12277]

This commit is contained in:
Oleksii Kriuchykhin 2025-09-19 14:14:32 +02:00
parent a44a419931
commit 73d42b1423
3 changed files with 33 additions and 27 deletions

View file

@ -148,10 +148,12 @@ class Protocol < ApplicationRecord
team_ids = teams.is_a?(ActiveRecord::Relation) ? teams.pluck(:id) : teams.id
if options[:in_repository]
protocols = latest_available_versions(team_ids).readable_by_user(user, team_ids)
protocols = latest_available_versions(team_ids)
readable_protocols = readable_by_user(user, team_ids)
protocols = protocols.active unless include_archived
else
protocols = joins(:my_module).where(my_modules: { id: MyModule.readable_by_user(user, team_ids) })
protocols = joins(:my_module)
readable_protocols = joins(:my_module).where(my_modules: { id: MyModule.readable_by_user(user, team_ids).select(:id) })
unless include_archived
protocols = protocols.active
.joins(my_module: { experiment: :project })
@ -159,22 +161,26 @@ class Protocol < ApplicationRecord
end
end
protocols = protocols.with(readable_protocols: readable_protocols)
.joins('INNER JOIN "readable_protocols" ON "readable_protocols"."id" = "protocols"."id"')
protocols.where_attributes_like_boolean(SEARCHABLE_ATTRIBUTES, query)
end
def self.where_children_attributes_like(query)
from(
"(#{unscoped.joins(:steps).where_attributes_like(Step::SEARCHABLE_ATTRIBUTES, query).to_sql}
unscoped_readable_protocols = unscoped.joins('INNER JOIN "readable_protocols" ON "readable_protocols"."id" = "protocols"."id"').select(:id)
unscoped.from(
"(#{unscoped_readable_protocols.joins(:steps).where_attributes_like(Step::SEARCHABLE_ATTRIBUTES, query).to_sql}
UNION ALL
#{unscoped.joins(steps: :step_texts).where_attributes_like(StepText::SEARCHABLE_ATTRIBUTES, query).to_sql}
#{unscoped_readable_protocols.joins(steps: :step_texts).where_attributes_like(StepText::SEARCHABLE_ATTRIBUTES, query).to_sql}
UNION ALL
#{unscoped.joins(steps: { step_tables: :table }).where_attributes_like(Table::SEARCHABLE_ATTRIBUTES, query).to_sql}
#{unscoped_readable_protocols.joins(steps: { step_tables: :table }).where_attributes_like(Table::SEARCHABLE_ATTRIBUTES, query).to_sql}
UNION ALL
#{unscoped.joins(steps: :checklists).where_attributes_like(Checklist::SEARCHABLE_ATTRIBUTES, query).to_sql}
#{unscoped_readable_protocols.joins(steps: :checklists).where_attributes_like(Checklist::SEARCHABLE_ATTRIBUTES, query).to_sql}
UNION ALL
#{unscoped.joins(steps: { checklists: :checklist_items }).where_attributes_like(ChecklistItem::SEARCHABLE_ATTRIBUTES, query).to_sql}
#{unscoped_readable_protocols.joins(steps: { checklists: :checklist_items }).where_attributes_like(ChecklistItem::SEARCHABLE_ATTRIBUTES, query).to_sql}
UNION ALL
#{unscoped.joins(steps: :step_comments).where_attributes_like(StepComment::SEARCHABLE_ATTRIBUTES, query).to_sql}
#{unscoped_readable_protocols.joins(steps: :step_comments).where_attributes_like(StepComment::SEARCHABLE_ATTRIBUTES, query).to_sql}
) AS protocols",
:protocols
)

View file

@ -173,9 +173,9 @@ class RepositoryRow < ApplicationRecord
def self.where_children_attributes_like(query)
query_clauses = []
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each_value do |config|
query_clauses << joins(config[:includes]).where_attributes_like(config[:field], query).to_sql
query_clauses << unscoped.joins(config[:includes]).where_attributes_like(config[:field], query).to_sql
end
from("(#{query_clauses.join(' UNION ')}) AS repository_rows", :repository_rows)
unscoped.from("(#{query_clauses.join(' UNION ')}) AS repository_rows", :repository_rows)
end
def self.filter_by_teams(teams = [])

View file

@ -48,31 +48,31 @@ class Result < ApplicationRecord
query = nil,
teams = user.teams,
_options = {})
new_query = joins(:my_module)
.where(
my_modules: {
id: MyModule.with_granted_permissions(user, MyModulePermissions::READ, teams).select(:id)
}
)
readable_results = joins(:my_module).where(my_modules: { id: MyModule.readable_by_user(user, teams).select(:id) })
results = joins(:my_module)
unless include_archived
new_query = new_query.joins(my_module: { experiment: :project })
.active
.where(my_modules: { archived: false },
experiments: { archived: false },
projects: { archived: false })
results = results.joins(my_module: { experiment: :project })
.active
.where(my_modules: { archived: false },
experiments: { archived: false },
projects: { archived: false })
end
new_query.where_attributes_like_boolean(SEARCHABLE_ATTRIBUTES, query)
results = results.with(readable_results: readable_results)
.joins('INNER JOIN "readable_results" ON "readable_results"."id" = "results"."id"')
results.where_attributes_like_boolean(SEARCHABLE_ATTRIBUTES, query)
end
def self.where_children_attributes_like(query)
from(
"(#{joins(:result_texts).where_attributes_like(ResultText::SEARCHABLE_ATTRIBUTES, query).to_sql}
unscoped_readable_results = unscoped.joins('INNER JOIN "readable_results" ON "readable_results"."id" = "results"."id"').select(:id)
unscoped.from(
"(#{unscoped_readable_results.joins(:result_texts).where_attributes_like(ResultText::SEARCHABLE_ATTRIBUTES, query).to_sql}
UNION
#{joins(result_tables: :table ).where_attributes_like(Table::SEARCHABLE_ATTRIBUTES, query).to_sql}
#{unscoped_readable_results.joins(result_tables: :table).where_attributes_like(Table::SEARCHABLE_ATTRIBUTES, query).to_sql}
UNION
#{joins(:result_comments).where_attributes_like(ResultComment::SEARCHABLE_ATTRIBUTES, query).to_sql}
#{unscoped_readable_results.joins(:result_comments).where_attributes_like(ResultComment::SEARCHABLE_ATTRIBUTES, query).to_sql}
) AS results",
:results
)