Commands

Commands are the higher building blocks of our application logic. They are mostly used to call services and format their results. They can only be called by controllers and their role is to verify the data they received and to format the output they get.

We use a custom ApplicationCommand class which is the parent class for all of our commands. This parent class inherits a custom lib class named Command, which defines the behaviour for every command.

They usually define a single public method named execute(params, context). For every command, this the method that will be called from the controller using appropriate params. This method will always return a result object (whose class is defined in our application_command.rb file). This result object will contain whether the command has been successful, the object the controller wants or the errors if there was any.

Usually, our command classes will return the result by calling one of the two methods defined in our lib file (command.rb):

  • success_result

  • error_result

Example

Here is the create method of our UsersController:

def create
  result = Users::CreateCommand.execute(new_user_params)

  if result.success?
    render json: Api::Private::UserSerializer.new(result.user), status: :created
  else
    render json: Api::Private::ErrorSerializer.new(result.errors), status: :unprocessable_entity
  end
end

We can see that we call the execute method of our Users::CreateCommand class with its appropriate params (new_user_params).

The command then returns its outcome in the result variable and we can then check whether or not this command is successful.

If it is, we want to send the newly created user back to the frontend. To do so, we can simply access it via the result object using result.user.

Check out our Users::CreateCommand class:

  class CreateCommand < ApplicationCommand
    def execute(params)
      return error_result(params) if params.invalid?

      user = UserService.create_user(params.user_attributes)

      success_result(user: user)
    rescue ActiveRecord::RecordNotUnique
      error_result(:not_unique, :email)
    end
  end

Here, we can see how params can be used: the first thing this command does, it to verify that the params are valid. If they're not, the command immediately returns using the method error_result passing the invalid params.

If the params are valid, the command simply creates a new user by calling the method create_user on the UserService and return success_result(user: user) which will later give us access to the user in the controller via result.user.

Check out the next section to know more about services!

Last updated