Rails Service Object

Tram Ho

Assuming we need to post a message to Twitter, we usually do the following:

Looking at the code above, we have defined send_tweet to call twitter api. What if another controller calls twitter in the same way? Should it be on concern ?? But it doesn’t really belong to the controller, why don’t we try to make the Twitter API an object then call when needed

What is a service object?

The service object is designed to implement a specific logic where the object handling k belongs entirely to a model. The benefit of the Service object is that it helps us to focus all the functional logic on a separate object instead of breaking it down into controller or model. Whenever needed, call that object. Because the logical block is concentrated in one object, it will greatly reduce the controller and model, the code is clean and the maintenance process will be less difficult as well. See the example on the send_tweet method, which implements the only logic that makes a tweet. If this logic is encapsulated into a class, we can initialize and call it as follows:

or

It’s convenient right k. We just define it once, can use it anywhere, easily maintance modification

Create Service object

We will create TweetCreator in app/services :

Add logic to the service:

You can then call by:

TweetCreator class name is relatively short but when initialized and called, it looks quite long right. we can shorten the call by the following, If TweetCreator can be similar to proc in Ruby we can call it with TweetCreator.call(message) Now we will turn the service object as a proc to facilitate calling service offline! Create 1 ApplicationService:

Every time the call is called, it will create an instance of that class vs the variables passed to it

At the controller we call

1 way to make the code more optimal right 😃 )

Grouping Similar Service Objects

In the above example we only consider one service object, but in reality it may be more complicated than that. For example, we have hundreds of services that handle many different logic. We can’t put them into one file, it will be difficult to manage, right. We will use namespacing, we will group the service objects with the same characteristics into one module: For example:

In service:

I called by

Service Objects manipulate the database

In the above example we considered the api call, but the service object can also be used to call the database. It is really useful to update multiple DBs with complex logic such as:

What should a service object return?

Recently we discussed how to construct a method call, so what should the method call return? There are 3 ways to return it

  • Returns true / false

  • Returns 1 value

  • Returns 1 enum

Some rules for writing good service objects

Each Service Object should have only 1 public method

Each service object only implements a specific bussiness, so there should only be one public method

Name the Service object according to its role

We should name the service object so that the code can understand its role as well

Do not perform multiple actions

Each service object only implements 1 bussiness

Handle Exceptions inside the service object

Hopefully the article helps you understand the service object and apply it in the project. Thanks for reading. 😄

Reference at: https://www.toptal.com/ruby-on-rails/rails-service-objects-tutorial

Share the news now

Source : Viblo