Created
September 5, 2014 21:24
-
-
Save mattbeedle/436f619e78047ba5e9ea to your computer and use it in GitHub Desktop.
Alternative Rails architecture with mediators and runners
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class API:V1::Companies | |
helpers do | |
def create_company_runner | |
CreateCompanyRunner.new(create_response, current_user, params[:company]) | |
end | |
def create_response | |
CreateResponse.new(self) | |
end | |
end | |
resource :companies do | |
post { create_company_runner.run } | |
end | |
end | |
class CreateResponse < SimpleDelegator | |
def creation_successful(company) | |
present :company, company | |
end | |
def creation_failed(form) | |
error!({ errors: form.errors }, 422) | |
end | |
end | |
class CreateCompanyRunner | |
include ActiveSupport::Rescuable | |
rescue_from RecordInvalidException, with: :invalid | |
pattr_initialize :listener, :user, :attributes | |
def run | |
validate! | |
create! | |
rescue Exception => e | |
rescue_with_handler(e) | |
end | |
private | |
def form | |
@form ||= CompanyForm.new(attributes) | |
end | |
def validate! | |
raise RecordInvalidException.new(form) unless form.valid? | |
end | |
def create! | |
mediator.call | |
listener.created_successfully mediator.company | |
end | |
def mediator | |
@mediator ||= CreateCompanyMediator.new | |
end | |
def invalid(exception) | |
listener.creation_failed(exception.record) | |
end | |
end | |
class CreateCompanyMediator | |
def initialize(user, attributes) | |
@user = user | |
@attributes = attributes.merge(default_attributes) | |
end | |
def call | |
create! | |
lookup_details | |
end | |
def company | |
@company ||= Company.new(attributes) | |
end | |
private | |
attr_reader :user, :attributes | |
def create! | |
repository.save! company | |
end | |
def default_attributes | |
{ user_id: user.id } | |
end | |
def lookup_details | |
company_lookup_job.async.perform(company) | |
end | |
def company_lookup_job | |
@company_lookup_job ||= CompanyLookupJob.new | |
end | |
def repository | |
@repository ||= CompanyRepository.new | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment