Radan Skorić
Business logic that changes the state of the system
class JobsController < ApplicationController #... def create @job = current_user.post_job(job_params) if @job.persisted? redirect_to jobs_path, notice: 'Job was successfully created.' else render :new end end def apply if current_user.apply_for_job(@job) redirect_to jobs_path, notice: 'You successfully applied to the job' else redirect_to jobs_path, alert: "You don't have the necessary skills" end end #... end
class User < ActiveRecord::Base has_many :jobs has_many :user_skills has_many :skills, through: :user_skills def post_job(job_params) job_params[:skills] &&= Skill.where(id: job_params.delete(:skills)).load jobs.create(job_params).tap do |job| if job.persisted? #Notify users with matching skills end end end def apply_for_job(job) return false if (self.skills & job.skills).size != job.skills.size #Notify job owner about application true end end
module JobPoster def post_job(job_params) job_params[:skills] &&= Skill.where(id: job_params.delete(:skills)).load jobs.create(job_params).tap do |job| if job.persisted? #Notify users with matching skills end end end end module JobApplicant def apply_for_job(job) return false if (self.skills & job.skills).size != job.skills.size #Notify job owner about application true end end
class User < ActiveRecord::Base has_many :jobs has_many :user_skills has_many :skills, through: :user_skills include JopPoster include JobApplicant end
class Job < ActiveRecord::Base ... after_create :notify_users_with_matching_skills ... end class JobApplication < ActiveRecord::Base ... validate :user_has_necessary_skills ... after_create :notify_job_owner ... end
class JobsController < ApplicationController #... def create job_params[:skills] &&= Skill.where(id: job_params.delete(:skills)).load @job = current_user.jobs.create(job_params) if @job.persisted? #Notify users with matching skills redirect_to jobs_path, notice: 'Job was successfully created.' else render :new end end def apply if (current_user.skills & job.skills).size == job.skills.size #Notify job owner about application redirect_to jobs_path, notice: 'You successfully applied to the job' else redirect_to jobs_path, alert: "You don't have the necessary skills" end end end
class User < ActiveRecord::Base has_many :jobs has_many :user_skills has_many :skills, through: :user_skills end
#app/forms/job_application_form.rb class JobApplicationForm include ActiveModel::Model attr_accessor :user, :job validates :user_has_necessary_skills def save # Notify job owner # ... # Create/Update real models as needed end private def user_has_necessary_skills (@user.skills & @job.skills).size != @job.skills.size end end
#app/controller/jobs_controller.rb def apply @form = JobApplicationForm.new(job_application_form_params).save if @form.persisted? redirect_to jobs_path, notice: 'Job was successfully created.' else render :new end end #app/models/job.rb class Job < ActiveRecord::Base belongs_to :user has_many :job_skills has_many :skills, through: :job_skills validates_presence_of :description end
#app/controller/jobs_controller.rb def create @job = JobPostingService.new(current_user).post(job_params) if @job.persisted? redirect_to jobs_path, notice: 'Job was successfully created.' else render :new end end def apply if JobApplicationService.new(current_user, @job).apply redirect_to jobs_path, notice: 'You successfully applied to the job' else redirect_to jobs_path, alert: "You don't have the necessary skills" end end
#app/models/user.rb class User < ActiveRecord::Base has_many :jobs has_many :user_skills has_many :skills, through: :user_skills end #app/models/job.rb class Job < ActiveRecord::Base belongs_to :user has_many :job_skills has_many :skills, through: :job_skills validates_presence_of :description end
#app/managers/base_service.rb class BaseService def initialize(performer) @performer = performer end end #app/managers/job_posting_service.rb class JobPostingService < BaseService def post(job_params) job_params[:skills] &&= Skill.where(id: job_params.delete(:skills)).load @performer.jobs.create(job_params).tap do |job| if job.persisted? #Notify users with matching skills end end end end
#app/managers/job_application_service.rb class JobApplicationService < BaseService def initialize(performer, job) @job = job super(performer) end def apply return false if (@performer.skills & @job.skills).size != @job.skills.size #Notify job owner about application true end end
class JobsController < ApplicationController #... def create @job = JobCreationContext.new(current_user, job_params).post_new_job if @job.persisted? redirect_to jobs_path, notice: 'Job was successfully created.' else render :new end end def apply if EmploymentNegotiationContext.new(current_user, @job).apply redirect_to jobs_path, notice: 'You successfully applied to the job' else redirect_to jobs_path, alert: "You don't have the necessary skills" end end #... end
#app/models/user.rb class User < ActiveRecord::Base has_many :jobs has_many :user_skills has_many :skills, through: :user_skills end #app/models/job.rb class Job < ActiveRecord::Base belongs_to :user has_many :job_skills has_many :skills, through: :job_skills validates_presence_of :description end
#app/contexts/post_job_context.rb class JobCreationContext def initialize(user, job_params) @user, @job_params = user, job_params @user.extend Employer end def post_new_job @user.post_job(@job_params) end end #app/contexts/apply_to_job_context.rb class EmploymentNegotiationContext def initialize(user, job) @user, @job = user, job @user.extend Developer end def apply @user.apply_for_job(@job) end end
#app/roles/employer.rb module Employer def post_job(job_params) job_params[:skills] &&= Skill.where(id: job_params.delete(:skills)).load jobs.create(job_params).tap do |job| if job.persisted? #Notify users with matching skills end end end end #app/roles/developer.rb module Developer def apply_for_job(job) return false if (self.skills & job.skills).size != job.skills.size #Notify job owner about application true end end