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)
invite.accept!(user)
UserMailer.invite_accepted(invite).deliver
end
end
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)
end
end
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?