← Back to Upcase

What about services objects?


(Guirec Corbel) #1

Hello,

What you think about service objects? I like to use this pattern when the controller have too many reponsabilities. For example, for me, a part of this code should be in a service object. I use this principle here.

What is your point of view?

If I understand as well, you use the principle “Fat Model, Skinny Controller” by default and If you feel than there is a problem, you use a design pattern. That’s it?

Thanks!


(Yannick Schutz) #2

I tend to use service objects if the responsibility does not belong to a model.

Plus that really helps me to do admin tasks in a console. I can mimic my controllers really easily that way.
But the thin line of defining where it belongs is mostly subjective.

I think a really good example of services object is the travis-ci core gem here on GitHub


(Guirec Corbel) #3

Do you think to create a class like UserCreator callable like this UserCreator.new(params).create. The responsability of this function is the creation process (create a user, send emails, do a particular treatment, etc…). A function User.create kind do the same job but it create big model with more dependencies. What you think?


(Yannick Schutz) #4

I actually have a CreateUser service.
I use most of my services passing all args to new and just call “#call” on them.
Now passing all args to the constructor or some options to the call method is a matter of taste for me.
If someone has great arguments in favor or against that would make me happy.


(Guirec Corbel) #5

This article is a good example of the reasons to use instance methodes instead class methods.


(Yannick Schutz) #6

I was wondering if CreateUser.new(params).call is better than CreateUser.new.call(params).


(Guirec Corbel) #7

If you whant, you can also call something like this :

class CreateUser 
   def self.call(params)
     self.new(params).call
   end

   def initialize(params)
     #...
   end

   def call
   end
end

To do a class with many function, it’s better to use params in the new. You can do something like this :

class User
  def initialize(params)
    #...
  end
 
  def create
    #...
  end
 
  def valid?
    #...
  end
end

To use CreateUser.new.call(params) or CreateUser.call(params) is the same thing.