Ruby on Rails provides everything you need to quickly create your application, but as your application starts to develop, you will experience situations where models and controllers swell, in branches, and difficult to control when dealing with complex business and logic, including functions that require us to interact with many different Models, not targeting a specific model.
Service Object is one of the solutions to this problem. It was born as a container for various business logic in which the processing object did not belong to any model.
The benefit of Service Object is that it helps us to focus all of the functionality logic into a separate object without having to subdivide it into controllers and models as usual. We always call that object when we need it. Because the logic block is focused on one object, it will minimize the controller and model a lot, the code clean and the maintain process is also less strenuous in the future.
service object class
classes are a good choice if you want to save data to instance variables.
def call(arg1, arg2, ...etc)
new(arg1, arg2, ...etc).call
def initialize(arg1, arg2, ...etc)
@var = arg1
@var = arg2
# Logic goes here
service object module
If you don’t want to save data to instance variables, then a module is a lighter option
def perform(arg1, arg2, ...etc)
# Logic goes here
how to use the service object
Normally in Rails system services will be concentrated in the app / services directory . Depending on the specificity and complexity of the project, we can subdivide the services into many sub-categories. In this example, I will create a service object named CalculatorService:
def initialize(number_1, number_2, method = nil)
@number_1 = number_1
@number_2 = number_2
@method = method
"You have not selected a calculation method"
attr_accessor :number_1, :number_2, :method
number_1 + number_2
number_1 - number_2
number_1 * number_2
return "Denominator cann't be zero" if number_2.zero?
(number_1 / number_2).to_f
The CalculatorService class is initialized with the parameters
number_1, number_2, method and has methods of
We can call the service object wherever and whenever we need to use it
result = CalculatorService.new(5, 7, :addition).perform
Note: if your service object is a module then you must include or extend it depending on your intended use.
The article aims to share a bit of my knowledge and basic usage of Service Object, the article is still limited, thank you for reading.
https://www.thegreatcodeadventure.com/service-objects-in-rails/ https://www.toptal.com/ruby-on-rails/rails-service-objects-tutorial https://blog.appsignal.com /2020/06/17/using-service-objects-in-ruby-on-rails.html