Service objects are Plain Old Ruby Objects used to extract code from a part of the application where it doesn’t really belong and isolate it in its own, testable file.
They often look like:
class ServiceObject def initialize(param1, param2) # set params end def do_something # do something end private def private_methods # end end
They can then be called like this:
class SomeController < ApplicationController service_object = ServiceObject.new(params[:a], params[:b]) if service_object.do_something # Happy path else # Sad path end end
This simplifies your controller and makes it much more understandable. It also separates the controller concerns (responding to requests and returning html/json/etc) from the service object concerns.
You will also see service objects that are structured like this:
class ServiceObject def self.call(params) # Do everything here end end
Which are then called like this:
class SomeController < ApplicationController if ServiceObject.call(params[:a]) # Happy path else # Sad path end end