Over the last couple of weeks we’ve been putting the various components together to creating a registration flow in Ruby on Rails.

In Part 1 we looked at building out the Model layer, which included the models for users, roles and assignments.

In Part 2 we added the register Form Object for encapsulating the process of registering as a new user and automatically getting assigned to the correct role.

In this final part we are going to be looking at adding the Controller and the View to allow the user to register with the application via the browser, as well as the Functional Tests required to assert that this functionality is working correctly.

Adding the Root Route

In today’s tutorial we’re going to be flexing the application as a whole, rather than just concentrating on the individual “units” in isolation.

Something that we’re not going to test, but we’re going to need is a root route. So to prevent any weird errors later down the line, I’ll just add this now.

Open up the routes.rb file under the config directory and then delete the comments:

Rails.application.routes.draw do

end  

The first route we will be adding will be for the root of the application:

Rails.application.routes.draw do  
root "home#index", as: :home  
end  

This will pass traffic from the root of the application to the index method on the HomeController.

So to make sure that works we need to create a new file called home_controller.rb under the app/controllers directory:

class HomeController < ApplicationController  
def index  
end  
end  

We also need to add a view for this route. Under app/views create a new directory called home.

Before I do this I’m first going to switch out the template engine for Slim. To do that, add the following line to your Gemfile:

gem "slim-rails"  

And then run the following command in Terminal:

bundle install  
[/bash]

Finally you can create a new file called `index.html.slim` under the `home` directory:  
```html  
h1 Welcome  

Now if you run the following command in Terminal and then go to http://localhost:3000 in your browser you should see the welcome page:

rails s  
[/bash]


## Displaying the Registration Form

In order for a user to register with the application, first we need to present them with an HTML form that they can submit.

So the first thing we need to do is to add the route. Open up the `routes.rb` file again and add the following route:  
```ruby  
Rails.application.routes.draw do  
root "home#index", as: :home

get "register", to: "register#new"  
end  

This will direct GET requests to /register to the new method on the RegisterController controller.

So next up we need to create the RegisterController. Create a new file called register_controller.rb under the app/controllers directory:

class RegisterController < ApplicationController  
def new  
@form = RegisterForm.new(User.new)  
end  
end  

The implementation of the new requires that we instantiate a new instance of the RegisterForm Form Object from last week and pass a new instance of the User model.

We also need to create a new view file that will generate the HTML form for this page. Create a new directory called register under the app/views directory and then create a new file called new.html.slim:

– if @form.errors.any?  
ul  
– @form.errors.full_messages.each do |msg|  
li = msg

= form_for @form, url: “register” do |f|  
div  
= f.label :email  
= f.text_field :email

div  
= f.label :password  
= f.password_field :password

div  
= f.submit “Register”  

We now have everything in place to display the form in the browser, but to assert that this is the case, we can add the first Functional Test.

Create a new file called register_controller_test.rb under the test/controllers directory:

class RegisterControllerTest < ActionController::TestCase  
test "should get register form" do  
get :new

assert_response :success  
end  
end  

In this test I’m making a GET request to the new method of the RegisterController and then asserting that the response is :success. If you run this test you should see it pass.

 bin/rake test test/controllers/register_controller_test.rb  
 [/bash]

As a final step of verification you can boot up the Rails server and go to [http://localhost:3000/register](http://localhost:3000/register) to see for yourself.


## Dealing with failed registrations

When a user registers for the application, there are a lot of things that could go wrong. For example, they might enter an email address that is missing, invalid, or already registered.

When this happens we want the user to be redirected to the form so they can correct their mistakes. In this next section we will implement the code to make this happen.

First up I will add a test to assert that the request fails when the data that has been provided is invalid:  
 ```ruby  
 test "should fail with invalid data" do  
 post :create, register: {email: "", username: "", password: ""}

 assert_response 400  
 end  

If you run the tests again you will see this fail because we have not created the route yet. I’m not going to step through each part of implementing this bit of functionality. If you want to see how the error messages guide you to what you should implement next I would encourage you to run the tests after each step of the following process.

First I’m going to add a new route to the routes.rb file:

Rails.application.routes.draw do  
root "home#index", as: :home

get "register", to: "register#new"  
post "register", to: "register#create"  
end  

Next I’m going to add the create method to the RegisterController Controller:

class RegisterController < ApplicationController  
def new  
@form = RegisterForm.new(User.new)  
end

def create

end  
end  

Next, I’m going to add a register_params method to get the parameters from the request:

private  
def register_params  
params.require(:register).permit(:email, :username, :password)  
end  

Finally I will implement the create method. First I will instantiate a new instance of the RegisterForm Form Object:

@form = RegisterForm.new(User.new)  

Next I will check to see if the request is valid by calling the validate method on the Form Object and pass it the return value of register_params:

if @form.validate(register_params)

else

end  

If the request is not valid I will render the :new method and set the HTTP response code to 400:

if @form.validate(register_params)  
@form.save  
redirect_to "/"  
else  
render :new, status: 400  
end  

The full controller will now look like this:

class RegisterController < ApplicationController  
def new  
@form = RegisterForm.new(User.new)  
end

def create  
@form = RegisterForm.new(User.new)

if @form.validate(register_params)

else  
render :new, status: 400  
end  
end

private  
def register_params  
params.require(:register).permit(:email, :username, :password)  
end  
end  

Now if you run the test again you should see it pass.

Dealing with successful registrations

Now that we have failing registrations taken care of, we can write the code to deal with valid registration requests.

First I will write a test to assert that this functionality is working correctly:

test "should register new user via html request" do  
post :create, register: attributes_for(:user)

assert_response 302  
end  

If you run this test you should see it fail because the request is not being redirected correctly when the form is saved.

To make this test pass we can implement the successful branch of the if clause inside of the create method of the RegisterControlller Controller:

class RegisterController < ApplicationController  
def new  
@form = RegisterForm.new(User.new)  
end

def create  
@form = RegisterForm.new(User.new)

if @form.validate(register_params)  
@form.save  
redirect_to "/"  
else  
render :new, status: 400  
end  
end

private  
def register_params  
params.require(:register).permit(:email, :username, :password)  
end  
end  

If you run those tests again you should see them all pass!

Conclusion

Congratulations! You have now successfully implement the registration process of your Ruby on Rails application.

Over the last couple of weeks we’ve put into place everything we’ve learned so far including creating Models, Form Objects, Controllers and Views, as well as writing Unit and Functional tests where appropriate.

We’ve also covered a lot of the little details around building a Rails application and we’ve developed a workflow for building out the required functionality.

The registration process in this mini series has been purposely kept fairly simple. In a real world application you will probably have to deal with a whole load of extra requirements for any particular application.

But hopefully you have learned enough of the basics to confidently go on and build your own registration process for your own Ruby on Rails application.

You can see all of the code from today’s tutorial on Github.