CRUD

In this recipe we'll create top-level CRUD services to manage our records.

This approach has been tested in production for many years and has saved significant time and effort.

Why

We want to put all the common logic for creating, updating, destroying and finding records in one place.

We want to minimize possibility of a mistake by putting logic as close to core as possible.

How to use it in controllers

class PostsController < ApplicationController
  def index
    render json: crud_find_all(Post)
  end

  def show
    render json: crud_find(Post)
  end

  def create
    render_service crud_create(Post)
  end

  def update
    render_service crud_update(Post)
  end

  def destroy
    render_service crud_destroy(Post)
  end
end

render_service method is a method from Rendering Services recipe.

How to use it in services

Customization

You don't need to create a new service for every CRUD operation. But you can create a service for specific model if you need to customize the behavior.

Just create a service called {Model}::Create, {Model}::Update, {Model}::Destroy and inherit from CreateRecordService, UpdateRecordService, DestroyRecordService respectively.

For example:

Adding additional steps to create user:

Setting default attributes:

Override attributes:

Skipping step:

Code

This code is just a starting point. You can customize it to fit your needs.

You need to add Pundit Authorization and Request Concern to make this code work.

app/services/create_record_service.rb:

app/services/update_record_service.rb:

app/services/destroy_record_service.rb:

app/controller/application_controller.rb:

app/controllers/concerns/crud_controllers.rb:

app/services/application_service.rb:

app/services/concerns/crud_services.rb:

app/services/concerns/request_concern.rb:

What's Next?

Learn how to render service results cleanly in your controllers:

Next: Service Rendering

Last updated