From 1765d83cd17cffbf1912015194f4c4ac1774207f Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Fri, 9 Mar 2018 11:05:43 +0100 Subject: [PATCH] Refactor search to support repository list items [SCI-2108] --- app/controllers/search_controller.rb | 10 +++---- app/models/repository.rb | 38 +++++++++++------------- app/models/repository_cell.rb | 15 ++++++++++ app/models/repository_row.rb | 43 ---------------------------- config/initializers/extends.rb | 8 ++++++ 5 files changed, 44 insertions(+), 70 deletions(-) diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 45b3395ea..19f912ba4 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -111,7 +111,6 @@ class SearchController < ApplicationController def count_by_repository count_total = 0 search_results = Repository.search(current_user, - true, @search_query, Constants::SEARCH_NO_LIMIT, nil, @@ -243,10 +242,11 @@ class SearchController < ApplicationController @repository_results = [] if @repository_search_count_total > 0 @repository_results = - RepositoryRow.search(@repository, @search_query, @search_page, - match_case: @search_case, - whole_word: @search_whole_word, - whole_phrase: @search_whole_phrase) + Repository.search(current_user, @search_query, @search_page, + @repository, + match_case: @search_case, + whole_word: @search_whole_word, + whole_phrase: @search_whole_phrase) end @search_count = @repository_search_count_total end diff --git a/app/models/repository.rb b/app/models/repository.rb index fce0a148d..f7ff892b6 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -23,40 +23,34 @@ class Repository < ApplicationRecord def self.search( user, - _include_archived, query = nil, page = 1, - current_team = nil, + repository = nil, options = {} ) - team_ids = - if current_team - current_team.id - else - Team.joins(:user_teams) - .where('user_teams.user_id = ?', user.id) - .distinct - .pluck(:id) - end + repositories = repository ? repository : Repository.where(team: user.teams) - row_ids = RepositoryRow - .search(nil, query, Constants::SEARCH_NO_LIMIT, options) - .select(:id) + includes_json = { repository_cells: Extends::REPOSITORY_SEARCH_INCLUDES } + searchable_attributes = ['repository_rows.name', 'users.full_name'] + + Extends::REPOSITORY_EXTRA_SEARCH_ATTR - new_query = Repository - .select('repositories.*, COUNT(repository_rows.id) AS counter') - .joins(:team) - .joins('LEFT OUTER JOIN repository_rows ON ' \ - 'repositories.id = repository_rows.repository_id') - .where(team: team_ids) - .where('repository_rows.id IN (?)', row_ids) - .group('repositories.id') + new_query = RepositoryRow + .left_outer_joins(:created_by) + .left_outer_joins(includes_json) + .where(repository: repositories) + .where_attributes_like(searchable_attributes, query, options) # Show all results if needed if page == Constants::SEARCH_NO_LIMIT new_query + .joins(:repository) + .select( + 'repositories.id AS id, COUNT(DISTINCT repository_rows.id) AS counter' + ) + .group('repositories.id') else new_query + .distinct .limit(Constants::SEARCH_LIMIT) .offset((page - 1) * Constants::SEARCH_LIMIT) end diff --git a/app/models/repository_cell.rb b/app/models/repository_cell.rb index 44ed0f77b..4da8e6fc7 100644 --- a/app/models/repository_cell.rb +++ b/app/models/repository_cell.rb @@ -2,6 +2,21 @@ class RepositoryCell < ActiveRecord::Base belongs_to :repository_row belongs_to :repository_column belongs_to :value, polymorphic: true, dependent: :destroy + belongs_to :repository_text_value, + (lambda do + where(repository_cells: { value_type: 'RepositoryTextValue' }) + end), + optional: true, foreign_key: :value_id + belongs_to :repository_date_value, + (lambda do + where(repository_cells: { value_type: 'RepositoryDateValue' }) + end), + optional: true, foreign_key: :value_id + belongs_to :repository_list_value, + (lambda do + where(repository_cells: { value_type: 'RepositoryListValue' }) + end), + optional: true, foreign_key: :value_id validates :repository_column, presence: true validate :repository_column_data_type diff --git a/app/models/repository_row.rb b/app/models/repository_row.rb index 5e9cfc320..3725852f1 100644 --- a/app/models/repository_row.rb +++ b/app/models/repository_row.rb @@ -21,47 +21,4 @@ class RepositoryRow < ApplicationRecord presence: true, length: { maximum: Constants::NAME_MAX_LENGTH } validates :created_by, presence: true - - def self.search(repository, query, page = 1, options) - new_query = distinct - .joins(:created_by) - .joins( - "LEFT OUTER JOIN ( - SELECT repository_cells.repository_row_id, - repository_text_values.data AS text_value, - to_char(repository_date_values.data, 'DD.MM.YYYY HH24:MI') - AS date_value - FROM repository_cells - INNER JOIN repository_text_values - ON repository_text_values.id = repository_cells.value_id - FULL OUTER JOIN repository_date_values - ON repository_date_values.id = repository_cells.value_id - ) AS values - ON values.repository_row_id = repository_rows.id" - ) - .where_attributes_like( - ['repository_rows.name', 'users.full_name', - 'values.text_value', 'values.date_value'], - query, options - ) - - if repository - new_query = new_query - .preload( - :repository_columns, - :created_by, - repository_cells: :value - ) - .where(repository: repository) - end - - # Show all results if needed - if page == Constants::SEARCH_NO_LIMIT - new_query - else - new_query - .limit(Constants::SEARCH_LIMIT) - .offset((page - 1) * Constants::SEARCH_LIMIT) - end - end end diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb index 96851f277..44c6d3781 100644 --- a/config/initializers/extends.rb +++ b/config/initializers/extends.rb @@ -43,6 +43,14 @@ class Extends REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0, RepositoryDateValue: 1, RepositoryListValue: 2 } + # Extra attributes used for search in repositories, text columns + # are only supported + REPOSITORY_EXTRA_SEARCH_ATTR = ['repository_text_values.data', + 'repository_list_items.data'] + + # Array of includes used in search query for repository rows + REPOSITORY_SEARCH_INCLUDES = [:repository_text_value, + repository_list_value: :repository_list_item] # List of implemented core API versions API_VERSIONS = ['20170715']