-
Notifications
You must be signed in to change notification settings - Fork 14
Rails Usage
Mike Nelson edited this page Jan 29, 2020
·
1 revision
When using Subroutine in a Rails application, you can avoid cluttering your controllers and models with code from specific use cases. Here's an example of how you could implement a signup flow:
app/
|
|- controllers/
| |- users_controller.rb
|
|- models/
| |- user.rb
|
|- ops/
|- signup_op.rb
resources :users, only: [] do
collection do
post :signup
end
end
When ops are around, the point of the model is to ensure data validity. That's essentially it. So most of your models are a series of validations, common accessors, queries, etc.
class User
validates :name, presence: true
validates :email, email: true
has_secure_password
end
I've found that a great way to handle errors with ops is to allow you top level controller to appropriately render errors in a consistent way. This is exceptionally easy for api-driven apps.
class Api::Controller < ApplicationController
rescue_from ::Subroutine::Failure, with: :render_op_failure
def render_op_failure(e)
# however you want to do this, `e` will be similar to an ActiveRecord::RecordInvalid error
# e.record.errors, etc
end
end
With ops, your controllers are essentially just connections between routes, operations, and whatever you use to build responses.
class UsersController < ::Api::Controller
def sign_up
# If the op fails, a ::Subroutine::Failure will be raised because we're invoking `submit!`.
op = SignupOp.submit!(params)
# If the op succeeds, it will be returned so you can access it's information.
render json: op.signed_up_user
end
end