So here is what I've come up with for the JobSearcher
.
Brian suggested that breaking this out into another controller which is what I started doing. I haven't looked too much into what the convention here is, so this is just a spike.
I applied what I learned from looking at the Sunspot source to make the searcher.
The main property that we seem to organize Jobs into is by state. From there, an aspect
can be called, returning a Sunspot object. I'm aware that some of this will become the responsibility of Tasks, but what I learned from looking at the Sunspot source can be applied to that as well.
There are still a few things yet to be implemented, but I thought I'd get some feedback before going forward:
- any pagination
- faceting for calendar views
- fulltext searches
- advanced filtering
Scripted::Application.routes.draw do
get 'job_states/:state', to: 'job_states#index'
get 'job_states/:state/:aspect', to: 'job_states#index'
# get 'job_states/in_authorship/:aspect', to: 'job_states#in_authorship'
# get 'job_states/plagiarized/:aspect', to: 'job_states#plagiarized'
# get 'job_states/needs_extra_review/:aspect', to: 'job_states#needs_extra_review'
# get 'job_states/in_extra_review/:aspect', to: 'job_states#in_extra_review'
# get 'job_states/fixing_extra_review/:aspect', to: 'job_states#fixing_extra_review'
# get 'job_states/needs_review/:aspect', to: 'job_states#needs_review'
# get 'job_states/needs_final_review/:aspect', to: 'job_states#needs_final_review'
# get 'job_states/any_state/:aspect', to: 'job_states#any_state'
# get 'job_states/reviewed/:aspect', to: 'job_states#reviewed'
# get 'job_states/in_any_edits/:aspect', to: 'job_states#in_any_edits'
end
class JobStatesController < ApplicationController
def index
if @searcher = JobSearcher.search(params)
render_results
else
render json: { error: { msg: 'you done messed up' } }
end
end
# def in_authorship
# @searcher = JobSearcher::InAuthorship.search(params)
# render_results
# end
# def plagiarized
# @searcher = JobSearcher::Plagiarized.search(params)
# render_results
# end
# def needs_extra_review
# @searcher = JobSearcher::NeedsExtraReview.search(params)
# render_results
# end
# def needs_review
# @searcher = JobSearcher::NeedsReview.search(params)
# render_results
# end
# def needs_final_review
# @searcher = JobSearcher::NeedsFinalReview.search(params)
# render_results
# end
# def any_state
# @searcher = JobSearcher::AnyState.search(params)
# render_results
# end
# def reviewed
# @searcher = JobSearcher::Reviewed.search(params)
# render_results
# end
# def in_any_edits
# @searcher = JobSearcher::InAnyEdits.search(params)
# render_results
# end
def render_results
render json: {
params: params,
hits: @searcher.hits.inspect
}
end
end
module JobSearcher
class Base
def self.search(params)
search_object = self.new(params)
aspect = params[:aspect] && params[:aspect].to_sym
if search_object.public_methods(false).include?(aspect)
search_object.send(aspect)
else
search_object.all
end
end
def initialize(params)
searchable_class = FinishedJob
setup = Sunspot::Setup.for(searchable_class)
@params = params.with_indifferent_access
@searcher = Sunspot.new_search(searchable_class)
@query = Sunspot::DSL::Search.new(searcher, setup)
end
private
attr_reader :params, :searcher, :query
def base_search
setup_perspective
query.order_by(:deadline_at, :asc)
searcher.execute
end
def setup_perspective
query.with(:needs_cc).equal_to(false) if admin?
query.with(:business_id).equal_to(params[:business_id]) if business?
query.with(:writer_id).equal_to(params[:writer_id]) if writer?
end
def admin?
params[:admin_id].present?
end
def business?
params[:business_id].present?
end
def writer?
params[:writer_id].present?
end
end
class InAuthorship < Base
def all
query.with(:state).equal_to(IN_AUTHORSHIP)
base_search
end
def specialists
query.with(:requires_expertise).equal_to(true)
all
end
def red_flags
query.any_of do
with(:flake_type, %w(implicit explicit))
with(:no_content).equal_to(true)
with(:writer_deadline_at).less_than(Time.now)
end
all
end
def unclaimed
query.with(:taken).equal_to(false)
all
end
def claimed
query.with(:taken).equal_to(true)
all
end
def superheroes
query.with(:flake_type, %w(implicit explicit))
claimed
end
end
class Plagiarized < Base
def all
query.with(:state).equal_to(PLAGIARIZED)
base_search
end
def ithenticate
query.with(:paraphrased).equal_to(false)
all
end
def paraphrased
query.with(:paraphrased).equal_to(true)
all
end
end
class NeedsExtraReview < Base
def all
query.with(:state).equal_to(NEEDS_EXTRA_REVIEW)
query.order_by(:deadline_at, :desc)
base_search
end
def by_admin
query.with(:extra_reviewer_type).equal_to('Admin')
all
end
def by_business
query.with(:extra_reviewer_type).equal_to('Business')
all
end
def by_editor
query.with(:extra_reviewer_type).equal_to('Writer')
all
end
end
class InExtraReview < Base
def all
query.with(:state).equal_to(IN_EXTRA_REVIEW)
base_search
end
end
class FixingExtraReview < Base
def all
query.with(:state).equal_to(FIXING_EXTRA_REVIEW)
base_search
end
end
class NeedsReview < Base
def all
query.with(:state).equal_to(NEEDS_REVIEW)
base_search
end
end
class NeedsFinalReview < Base
def all
query.with(:state).equal_to(NEEDS_FINAL_REVIEW)
base_search
end
end
class AnyState < Base
def all
query.order_by(:deadline_at, :desc)
base_search
end
end
class Reviewed < Base
def all
query.with(:state).greater_than(NEEDS_FINAL_REVIEW)
query.order_by(:deadline_at, :desc)
base_search
end
end
class InAnyEdits < Base
def all
query.with(:state, [FIXING_PLAGIARISM, FIXING_EXTRA_REVIEW, NEEDS_EDITS])
query.with(:sent_to_writer_at).less_than(2.days.ago) if admin?
base_search
end
end
end