-
Notifications
You must be signed in to change notification settings - Fork 0
The best service object (for us)
Bogusław Tolarz edited this page Aug 10, 2018
·
1 revision
class Service
def call
puts 'hello'
end
end
Service.new.call
class Service
def call
set_as_completed or cancel
end
end
Sometimes when multiple steps are involved to fulfill the responsibility of a service object, it might be a good idea to wrap the steps in a transaction, so that if any of the steps fails, we can always rollback the changes made in previous steps. (2)
USE TRANSACTION ONLY FOR DB OPERATIONS
class Service
def call
ActiveRecord::Base.transaction do
assign_line_items
calcuate_totals
set_as_completed or cancel
end
end
end
Result = Struct.new(:success, :value) do
def success?
success
end
def failure?
!success
end
end
Result.new(true, "Message sent!")
class Service
def initialize(facebook_adapter: FacebookAdapter.new)
@facebook_adapter = facebook_adapter
end
def call(params)
if @facebook_adapter.send_message(params[:user_id, params[:message])
Result.new(true, "Message was sent")
else
Result.new(false, "Some error occured")
end
end
end
Service.new.call(123, "Please try Spree Commerce if you need good ecommerce framework")
https://github.com/tier-tools/chainit
class UserUpdater
def call
ChainIt
.chain { FindUser.call(1) }
.chain { UpdateUser.call(email: '[email protected]') }
.chain { p :success}
.result
end
end
module ServiceObject
extend ActiveSupport::Concern
module ClassMethods
def call(*args)
new.call(*args)
end
end
def call
raise NotImplementedError
end
end
Service.call(args)
instead of Service.new(args).call
.
Call method is important. Really.
shared_examples_for "service object" do
it { expect(subject.call).to_not raise_error }
end
- The Power of Interfaces in Ruby - Shiroyasha
- Essential RubyOnRails patterns — part 1: Service Objects
- A Case For Use Cases - We build Envato
- Struct inheritance is overused - The Pug Automatic
- The 3 Tenets of Service Objects in Ruby on Rails – Hacker Noon
- Chain service objects like a boss – Benjamin roth – Medium