The default way of handle business logic in Rails is “Thin controller, fat model”. In most projects I participated, we were using the concept of “Service objects”. Can we have some default way of implementing Services, which is supported by Rails core?
Speaking for myself…
You can put POROs (Plain Old Ruby Objects) in
app/models and even nest them in folders for namespacing. I could never understand the reasoning for creating a separate
app/services folder — maybe because some folks think only ActiveRecord models can go in the models folder?
Maybe that just needs to be documented more clearly.
I see the reason of
app/service folder for separation of concepts of
data layer and
data manipulations layer. When they are all mixed, it becomes difficult to find the purpose for each.
Without looking into DB, you can’t say for sure wether it is PORO or AR class.
POROs are good but they lack common answers to how services should accept arguments, how they should be called, what they should return, how they should be named, how they can be composed, etc. I wrote actor because I think it’s valuable to answer these questions and harmonize an application’s “verbs”. I would love it if Rails helped show the path from the start. It could help people better seperate these concerns and perhaps provide a basic framework to the concept of “services”, as it does with “jobs”.
In my (probably) limited experience, the
app/services directories I’ve seen in Rails apps over the years have become junk drawers. In the past few years I’ve strived to give things names and pull out domain objects specific to my app. Also when I’ve felt like I need a “service” object because there’s a complex set of steps involving multiple models, I stop and ask if there’s really a hidden model in there, or perhaps I need more or different controllers, and more often than not I reorganize my app and get a better solution than I would have had with the service object.
I agree with @Eric_Hayes’s perspective here, but per this thread, An extensive example of project organization, and … many legacy Rails projects I’ve worked on … I think that this perspective is something a lot of folks really, really don’t find obvious. I wonder if there are ways to make it clearer?
Agree with @Eric_Hayes and @Betsy_Haibel here (as someone who wrote a blog post about this very topic!). But since it’s a point that never goes away, I wonder if it’s possible to do a better job with documentation/default folder structure/etc. so people who want their AR objects separated from other domain-level logic don’t struggle as much.
It’s true that app/services can get into a cluttery mess - but if anything, it’s better than have both service objects and models get into a cluttery mess in app/models. I’d definitely like to see this happen.
If you like ActiveRecord, you can checkout this for creating service objects for your business logic.