In a previous post we saw how to create service objects with CRUD interface. Now let’s see why you should care it is useful.
REST architecture is about CRUD over http. Rails uses RESTful routes. And in every RESTful controller action you may find something like this:
Not very DRY, isn’t it? The only differences between these actions are:
Method called on a model
Action on success
Action on error
Text in flash message on success
Text in flash message on error
What if we can extract them? We can decide which method to call on a model, where to redirect/render after, which flash messages to show by inspecting the model itself and a controller’s action.
But this is fine when you are dealing with ActiveRecord (ActiveModel to be precise) models. What if we are using service objects? One of the “canonical” way to use service objects is by calling call method, like this:
Again, not very DRY. And here comes services which behave like ActiveModel and use CRUD interface.
Also, let’s add some magic method which will call appopriate method on an object, redirect and show flashes:
What inside magic function?
Check which actions it is called from by inspecting caller
Call save or destroy according to the action
Redirect to appropriate url or render a template according to result of calling save or destroy
Show appropriate flash messages. In case of error - extract messages from errors object
Not so magic, isn’t it? Luckily you don’t have to implement all this logic because I’ve already done this in crud_responder gem.
Now it’s very handy to have all domain objects (models and services) with CRUD interface so you can use them in controllers without worrying whether it’s ActiveRecord model or a service object.