From c0bdb47d43c57de2705d2df1647469f11c857450 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 30 Nov 2022 02:03:28 -0800 Subject: [PATCH] Add scoped search for job skills --- app/controllers/api/v1/api_controller.rb | 3 +- app/controllers/api/v1/search_controller.rb | 49 +++++++++++++++++++- app/errors/api/v1/NoJobProvidedError.rb | 22 +++++++++ app/models/job_skill.rb | 20 ++++++++ app/views/api/v1/search/job_skills.json.rabl | 11 +++++ config/routes.rb | 1 + 6 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 app/errors/api/v1/NoJobProvidedError.rb create mode 100644 app/views/api/v1/search/job_skills.json.rabl diff --git a/app/controllers/api/v1/api_controller.rb b/app/controllers/api/v1/api_controller.rb index 424b216..e9dcb95 100644 --- a/app/controllers/api/v1/api_controller.rb +++ b/app/controllers/api/v1/api_controller.rb @@ -11,6 +11,7 @@ module Api::V1 rescue_from ActiveRecord::RecordNotUnique, with: :render_unprocessable_entity_response rescue_from Api::V1::SameFavoriteUserError, with: :render_unprocessable_entity_response rescue_from Api::V1::FavoriteAlreadyExistsError, with: :render_unprocessable_entity_response + rescue_from Api::V1::NoJobProvidedError, with: :render_unprocessable_entity_response rescue_from Api::V1::UnauthorizedError, with: :render_unauthorized_response rescue_from ActionController::ParameterMissing, with: :render_unprocessable_entity_response @@ -63,4 +64,4 @@ module Api::V1 raise UnauthorizedError unless current_user end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index f3230a7..1701b51 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -76,10 +76,57 @@ class Api::V1::SearchController < Api::V1::ApiController @summons = @summons.paginate(page: search_params[:page], per_page: 10) end + def job_skills + raise Api::V1::NoJobProvidedError unless search_params[:job].present? + + # Set up basic parameters we'll use + job = Job.find(search_params[:job]) + locale = search_params[:locale] || 'en' + group = search_params[:group].to_i unless !search_params[:group].present? + + # Set the conditions based on the group requested + conditions = {} + if (group) + if (group < 4) + conditions[:color] = group + conditions[:emp] = false + conditions[:base] = false + elsif (group == 4) + conditions[:emp] = true + elsif (group == 5) + conditions[:base] = true + end + end + + # Perform the query + if search_params[:query].present? && search_params[:query].length >= 2 + @skills = JobSkill.method("#{locale}_search").(search_params[:query]) + .where(conditions) + .where(job: job.id, main: false) + .or( + JobSkill.method("#{locale}_search").(search_params[:query]) + .where(conditions) + .where(sub: true) + ) + else + @skills = JobSkill.all + .where(conditions) + .where(job: job.id, main: false) + .or( + JobSkill.all + .where(conditions) + .where(sub:true) + ) + end + + @count = @skills.length + @skills = @skills.paginate(page: search_params[:page], per_page: 10) + end + private # Specify whitelisted properties that can be modified. def search_params params.require(:search).permit! end -end \ No newline at end of file +end diff --git a/app/errors/api/v1/NoJobProvidedError.rb b/app/errors/api/v1/NoJobProvidedError.rb new file mode 100644 index 0000000..6727873 --- /dev/null +++ b/app/errors/api/v1/NoJobProvidedError.rb @@ -0,0 +1,22 @@ +module Api::V1 + class NoJobProvidedError < StandardError + def http_status + 422 + end + + def code + "no_job_provided" + end + + def message + "A job ID must be provided to search for job skills" + end + + def to_hash + { + message: message, + code: code + } + end + end +end diff --git a/app/models/job_skill.rb b/app/models/job_skill.rb index 9705435..8e47fbe 100644 --- a/app/models/job_skill.rb +++ b/app/models/job_skill.rb @@ -1,6 +1,26 @@ class JobSkill < ApplicationRecord + include PgSearch::Model + belongs_to :job + pg_search_scope :en_search, + against: :name_en, + using: { + tsearch: { + prefix: true, + dictionary: "simple" + } + } + + pg_search_scope :jp_search, + against: :name_jp, + using: { + tsearch: { + prefix: true, + dictionary: "simple" + } + } + def display_resource(skill) skill.name_en end diff --git a/app/views/api/v1/search/job_skills.json.rabl b/app/views/api/v1/search/job_skills.json.rabl new file mode 100644 index 0000000..100cca8 --- /dev/null +++ b/app/views/api/v1/search/job_skills.json.rabl @@ -0,0 +1,11 @@ +node :count do + @count +end + +node :total_pages do + (@count.to_f / 10 > 1) ? (@count.to_f / 10).ceil() : 1 +end + +node(:results) { + partial('job_skills/base', object: @skills) +} unless @skills.empty? diff --git a/config/routes.rb b/config/routes.rb index 44260c7..d722ad4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,6 +25,7 @@ Rails.application.routes.draw do post 'search/characters', to: 'search#characters' post 'search/weapons', to: 'search#weapons' post 'search/summons', to: 'search#summons' + post 'search/job_skills', to: 'search#job_skills' get 'jobs', to: 'jobs#all'