I have a colleague that likes to pass off the controller into a service object. For example a controller method might look the following way:
class FooController < ApplicationController
...
def show
Foo.new(self).call
end
...
end
the service object looks like this then:
class Foo
attr_reader :controller, :resource_id
delegate :render, :params, :head, to: :controller
def initialize(controller, resource_id)
@controller = controller
@resource_id = resource_id
end
def call
resource = SomeActiveRecordModel.find(resource_id)
if resource
render json: resource.to_json
else
head :not_found
end
end
end
Somehow I feel that this is counterproductive and an instance of cargo-cult software engineering.
I would prefer to keep the service object completely separate from the controller. Dependencies would be passed into the service object's constructor, parameters would be passed into the service object as method arguments. Any result is simply returned from the method.
Sadly my colleagues are not exactly thrilled by this whenever I bring it up in a code review, which I in turn find relatively frustrating.
What are the pros an cons of the respective approaches? How can I argue my case better? Am I missing something here?
I suspect the answer is "it depends".
In the exact example you gave, I see no particular advantage and it creates a degree of obfuscation. Also, in general, I agree with you on keeping the service object separate from the controller.
However, there are times when I find myself passing the controller into the service object. For instance, when I have a lot of complex work to do in dynamically constructing a view.