I'm writing a basic search engine for my website.
It works but I'm really unhappy with the code. I know it can't be improved but I'm lacking some experiences here. In my params from my search I get:
{"utf8"=>"✓", "authenticity_token"=>"aNY2ZVpeyZsLnIVegQPpPz/22VYx2ug+tbfu0Nzngac=", "skills"=>"3,8", "country"=>"USA", "state"=>"TX", "city"=>"Paris", "commit"=>"Search", "controller"=>"jobs", "action"=>"index"}
Here is my controller:
class JobsController < ApplicationController
before_action :authenticate_user!, :except => [:index]
def index
search_jobs
end
def search_jobs
search_filters = search_params
if search_filters.present?
skills = search_filters[:skills]
city, state, country = search_filters[:city], search_filters[:state], search_filters[:country]
search_jobs = Job.select(:id).joins(:skills)
search_jobs = search_jobs.where(build_where(skills)) if skills.present?
search_jobs = search_jobs.group("jobs.id")
search_jobs = search_jobs.group("jobs.city, jobs.state") if city.present? || state.present?
search_jobs = search_jobs.group("jobs.created_at")
search_jobs = search_jobs.order("city <> '#{city}'") if city.present?
search_jobs = search_jobs.order("state <> '#{state}'") if state.present?
search_jobs = search_jobs.order("country <> '#{country}'") if country.present?
search_jobs = search_jobs.order("count(*) desc")
search_jobs = search_jobs.order('jobs.created_at DESC')
jobs_id = search_jobs.map(&:id)
end
jobs = Job.includes(:company, :skills)
jobs = jobs.where(id: jobs_id) if jobs_id.present?
jobs = jobs.most_recent
@jobs = jobs
end
def build_where(skills_filters)
skills = skills_filters.split(", ")
query = "'skills'.'id' = #{skills.first}"
skills.shift
skills.each do |skill|
query << " OR 'skills'.'id' = #{skill}"
end
return query
end
private
def search_params
params.permit(:skills, :country, :city, :state)
end
end
Few, things:
- I'm not happy with the build_where method, but I can't think of a way to build a where dynamically based on the skills the users are looking for.
- The search_jobs seems the be a bad idea. When I run this in the developer console it looks like each line is executing a SQL query which is an issue performance wise. 10 queries to get a list of IDs seems to be terrible
- Then I'm doing 3 more queries afterward: to get all the jobs with all the information needed.
So, I think my code is not really good, but I'm not sure how I can improve it. My goal overall is