This post is notes from the fantastic course Refactoring Rails
— If you are a rails dev, strongly recommend you check it out.
If your rails app has any routes or controller actions that are outside of the RESTful
actions, change it! Split it out into routes / controllers / actions that are very straightforward CRUD
Routes should follow the a noun#verb convention. For example: users#show, should never follow a pattern of noun#verb_noun for example users#make_admin. This is a clear sign that there is an object just waiting to be promoted to a first class citizen.
Essentially, never do anything but CRUD on anything. So if you have a controller action like make_admin on a controller, then it should be promoted to a "First Class Citizen"
Making things a "First Class Citizen"
- Give it a Name. In this case an Admin is a type of a User.
- Give it a route, in this case we can create resource :administrators
- Give it a controller then, it gets it's own controller
This moves our messy make_admin route and controller action and turns it into a super clean new admin route and controller.
Objects With Side Effects
Rails is simple when you just need to interact with a single object. But the real world is messy. Many use cases require interacting with many objects in a single controller. There's side effects and other dependencies, not just a single object. Example: An order refund controller not only needs to update an order object, but send a refund email and actually reverse the payment using stripe API.
That's like 3 things to do with a single "Create Refund" action. It's easy to shove all that functionality into a long controller method. Or to couple all this functionality into a model method.
A much better approach is to create a Service Object
, then you can just CRUD a single service object that encapsulates all the dependent actions. Continuing the example of the "Order Refund" if we spin up a model to handle this we can have a single method called from the Refunds controller that can call the issue method from the service object. This object can then be the single source of truth on all the actions needed to actually handle the logic and side effects of the refund.