Building out a User Confirmation flow in Trailblazer

In this application I need 3 different ways of creating new users. Firstly, I need to import users from the old WordPress application. Secondly, I need to create confirmed users to seed the database. And finally, I need the default Operation that will be used as part of the registration process.

When a user registers with the application using the default Operation, I will send a confirmation email that will allow the user to confirm their email address.

But I also need a way to allow imported users to confirm their email address, as well as choose a username, and a password.

In today’s tutorial we’re going to be looking at adding the functionality to request a confirmation email. This will touch upon a couple of interesting aspects of Trailblazer Operations that we haven’t covered so far, and it will hopefully reinforce how Trailblazer fits inside of a typical Rails application.

So with that being said, lets get started!

How is this going to work?

Before we jump into the code, lets have a quick review of what we’re going to build.

We’re first going to need two new routes. One for displaying a form that accepts an email to send the confirmation email to, and one to accept the POST request from the form.

We will need a Controller to accept those requests and we need to create the UserMailer class, and email view template.

We will need to update the User::Create::Operation::Default class to send a confirmation automatically after saving the new user and we will need to create a new Operation for requesting a confirmation email.

We will need to create a new Cell class and view template for displaying the form, and of course we will need a bucket load of tests to make sure everything is working as it should.

Phew! We best get started then!

Setting up the routes

The first thing we need to do is to add two new routes to the routes.rb under the config directory:

There is going to be a request action and a confirm action for this confirmation process.

As you might have noticed, I’m going to separate these two actions into two separate controllers under the Confirmation namespace.

I would rather keep this as two small Controllers, rather than one bigger Controller.

Adding the Controller

Next up I will add the Controller to handle the requests:

module Confirmation
class RequestController < ApplicationController
def new
form Confirmation::Request::Operation
end
def create
run Confirmation::Request::Operation do |op|
return redirect_to login_url
end
render :new, status: 400
end
end
end

There isn’t a great deal going on in this Controller, which is a lovely side-effect of using Trailblazer. If you have been following along with these Trailblazer tutorials this is going to look very familiar.

I’ve added the Confirmation::Request::Operation even though I haven’t created it yet because I know exactly what this Controller is going to look like when all the pieces are in place.

Creating the Cell

module Confirmation::Request
class Cell < Culttt::Cells::Form
def show
render
end
end
end

Once again I’m extending Culttt::Cells::Form from last week’s tutorial. This is also a really basic example of a Cell class, and so there isn’t any additional logic that is required in the class itself.

If you missed the setup to this kind of testing from Getting started with Trailblazer Cells, I would recommend that you go back and take a look. I really love how easy it is to test Cells in isolation.

Adding Controller Tests

With all of the functionality in place, we can add some Controller tests to set through the process and ensure everything is working as it should:

Hopefully this reads well and you’re familiar with what we’re testing. I’m basically just walking through the business rules and checking that they fail. I don’t check the actual errors for each case because I’m already check them at the Unit level.

In the final test I’m asserting that the request was successful and that the email was sent correctly.

Conclusion

Hopefully today’s tutorial was beneficial in that it was an example of where we’re using an Operation to perform a process that is not directly creating or updating a 1-to-1 resource.

Despite this we have still used many of the same techniques that we’ve been building up over the last couple of weeks.

Building out this functionality can often be boring. This kind of boiler plate code is basically the same for just about every type of web application.

But hopefully you can see how nice and simple Trailblazer makes it so you don’t have to worry about too much complexity.