Struggling to organize code in Rails
Published Nov 10, 2020
Okay internet, here’s something I’ve been struggling with in Rails: how do I organize code that doesn’t fit into one of the framework concepts? In particular, I’m trying to write some code that works with data from about 5 models, is not involved in HTTP requests, will be used by an asynchronous background job, and is reusable outside the context of that job.
I’ve heard of service objects / service classes, but there’s no real “service” that this behavior is a part of.
It doesn’t make sense to put it on any one of the models because it’s more business code than data code.
I really dislike working with code that makes me do ThingDoer.new.update_stuff(arg)
.
Maybe it’s aesthetics, but I also don’t like creating a whole new object that performs a single function and has no state.
Do I create a new module with a single function and call it as ThingUtils.update_stuff(arg)
?
Does it make testing weird when a module does database things?
Should I shoehorn a service definition and call it as ThingService.new.update_stuff
?
That feels like over-engineering if .new
doesn’t take any arguments.
In procedural or functional programming, I’d define a top-level function in a module that gets imported as the name service
.
So I’d be able to do service.update_stuff(arg)
.
Is the idea that Ruby trades out import service
for service = Service.new
?
Is there some pattern here that I don’t have enough object-oriented programming experience to see? This is making me think that I’m missing some really obvious basic software design principle.