One challenge I regularly face is how to name my service objects in Rails.

I like the advice in this blog post on Gourmet Service Objects, a service object performs one action. It holds the business logic to perform that action. For example:

# app/services/accept_invite.rb
class AcceptInvite

  def self.call(invite, user)


However, I frequently find that my class names are rarely this short.

For example, I have areas that have many runners that have many goals. I want to calculate, for a given area, the percentage of runners with a goal set.

Adhering to the above idea, that a service object performs one action, I've come up with the following:

# app/services/get_percentage_of_runners_with_goals.rb
class GetPercentageOfRunnersWithGoals

  def self.call(area)
    membership_count = area.runners.members.to_float
    goals_set_count = area.runners.with_goals.to_float
    percentage = goals_set_count / membership_count
    (percentage * 100).to_s(:percentage, precision: 0)


What then tends to happen is I have hundreds of these service objects, named along the lines of VerbObjectForObject, i.e. GetMembershipStatusOfRunner, GetCurrentGoalOfRunner, SetGoalOfRunner, and so on.

Is there a better naming convention?


You could use modules to group them which would potentially shorten the names too. You'd probably need to look at the types of service methods you have before deciding how to group them (e.g. by model: Runner::MembershipStatus or activity: Statistics::RunnersWithGoals).

Presumably you've already decided you don't want these methods on your models? For me a service method makes most sense if it's performing an action rather than just retrieving some information. So GetCurrentGoalOfRunner would probably sit on my Runner model as runner.current_goal rather than being a separate service.

Possibly also worth looking at Mutations (which I was introduced to recently): https://eng.uservoice.com/blog/2013/02/27/introducing-mutations-putting-soa-on-rails-for-security-and-maintainability/


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.