Service Objects are classes or modules that have one public method, often named #call, and are designed to perform a single task or service.
Service objects are single business actions.
Example:
class ServiceObject
def call(arg1, arg2, ...etc)
new(arg1, arg2, ...etc).call
end
def initialize(arg1, arg2, ...etc)
@var = arg1
@var = arg2
...etc
end
private
def call
# Logic goes here
end
end
module ServiceObject
def self.call(arg1, arg2, ...etc)
# Logic goes here
end
end
-
Does your code handle routing, params or do other controller-y things? If so, don’t use a service object—your code belongs in the controller.
-
Are you trying to share your code in different controllers? In this case, don’t use a service object—use a concern.
-
Is your code like a model that doesn’t need persistence? If so, don’t use a service object. Use a non-ActiveRecord model instead.
-
Is your code a specific business action? (e.g., “Take out the trash,” “Generate a PDF using this text,” or “Calculate the customs duty using these complicated rules”) In this case, use a service object. That code probably doesn’t logically fit in either your controller or your model.
-
Only One Public Method per Service Object We should choose the name of this method:
.call
,.perform
,.run
,.execute
, etc. -
Name Service Objects Like Dumb Roles at a Company
TweetReader
,TweetCreator
,EventsManager::Create
,EventsManager::Update
,EventsManager::Finder
,... -
Don’t Create Generic Objects to Perform Multiple Actions
-
Handle Exceptions Inside the Service Object
- Name of the public method. We can then define services that inherit from this class:
# app/services/application_service.rb
class ApplicationService
def self.call(*args, &block)
new(*args, &block).call
end
end
- Any constrains on the allowed return values? A boolean, a value, an enum, an object with result status?
In favour:
- https://www.toptal.com/ruby-on-rails/rails-service-objects-tutorial
- https://aaronlasseigne.com/2017/11/08/why-arent-we-using-more-service-objects-already/
- https://medium.freecodecamp.org/service-objects-explained-simply-for-ruby-on-rails-5-a8cc42a5441f
- https://medium.freecodecamp.org/ruby-on-rails-how-to-extract-code-to-service-objects-1c73148cc715
Against: