I want to move some rails business logic into a service, following correct OOP protocol. I'm following the method recommended here: Private module methods in Ruby
Ultimately, I want to move business logic out of models and controllers into services, which are Plain Old Ruby Objects. So, models will just be concerned with persistence, scoping, & validation.
Is this the correct way to make a service module?
Version 2:
module CategorizeJobs
def self.fetch( location, category_name )
c = Categorizer.new( location, category_name )
c.get_jobs
end
class Categorizer
def initialize(location, category_name)
@location = location
@category_name = category_name
end
def get_jobs
job_ids = get_correct_jobs
Category.includes(:jobs).where( jobs: { id: job_ids } )
end
private
def get_correct_jobs
jobs = filter_by_location
jobs = filter_by_category(jobs)
jobs.collect(&:id)
end
def filter_by_category(jobs)
return jobs unless @category_name.present?
category = Category.where(name: @category_name).first
if category
jobs = jobs.where(category: category)
end
jobs
end
def filter_by_location
if @location.present?
jobs = get_jobs_at_location
else
jobs = Job.open
end
end
def get_jobs_at_location(location)
Job.joins(:location).within(20, origin: @location).open
end
end
end
Version 1:
module CategorizeJobs
def self.fetch( location, category_name )
c = Categorizer.new
c.perform( location, category_name )
end
class Categorizer
def perform( location, category_name )
job_ids = get_correct_jobs(location, category_name)
Category.includes(:jobs).where( jobs: { id: job_ids } )
end
private
def get_correct_jobs(location, category_name)
jobs = filter_by_location(location)
jobs = filter_by_category(jobs, category_name)
jobs.collect(&:id)
end
def filter_by_category(jobs, category_name)
return jobs unless category_name
category = Category.where(name: category_name).first
if category
jobs = jobs.where(category: category)
end
jobs
end
def filter_by_location(location)
if location
jobs = get_jobs_at_location(location)
else
jobs = Job.open
end
end
def get_jobs_at_location(location)
Job.joins(:location).within(20, origin: location).open
end
end
end