Complete Rails 6 Example — Part 2
What are we trying to achieve?
In this second part of the Rails complete application guide, we will be adding authentication to our new app. There’s nothing to see yet in our app, but for many programming problems (and in our case) we will need to protect some functionalities of our solution to be viewable only for registered users.
So we are going to add an authentication method to our recent created Rails app and make it look good with some Bootstrap styles.
Adding authentication
Add gem devise to your Gemfile, just adding this line:
# Gemfile
gem 'devise'
Then bundle to install it. As we are working with a Dockerized Rails application, we will need to rebuild our image with build command. Remember inside the Dockerfile for “web” container, we include “bundle install”.
> docker-compose down
> docker-compose build
After it, we need the basic scaffold, and devise facilitate it to us the following command:
> docker-compose run --rm web rails g devise:install
You get it right? Yes, this is the way we are going to run Rails commands directly into the web container because we don’t have Ruby installed in our local machine, it’s inside a Docker container.
Now we will need to set up the default URL options for the Devise mailer in each environment. So in the file config/environments/development.rb, add this line:
# config/development.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
Among other instructions, we will need to add the following HTML elements to the file called application.html.erb (above “<%= yield %>”). This is the piece of code that will render our error messages, and we will be able to customize it anytime.
<% if alert.present? %>
<div class="alert alert-warning" role="alert">
<p><%= alert %> </p>
</div>
<% end %>
<% if notice.present? %>
<div class="alert alert-info" role="alert">
<p><%= notice %> </p>
</div>
<% end %>
In the same file, to correctly load CSS styles, let’s change stylesheet_link_tag to stylesheet_pack_tag, like this:
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
The next step is to generate the User model structure Devise needs. It will be accomplished with the following command:
> docker-compose run --rm web rails g devise User
Now we will generate the views that devise gem offers to us.
> docker-compose run --rm web rails g devise:views
And finally, we will create a controller for our main view (Let’s call it “Home”), with this command:
> docker-compose run--rm web rails g controller pages home
Now add those changes to the database
> docker-compose run --rm web rake db:migrate
As in the previous article, if we are using Linux, the generated files will belong to root user, so we will need to change that:
> sudo chown -R $USER:$USER .
Now inside routes.rb file, change get ‘pages/home’
# routes.rb
root to: 'pages#home'
Now add the basic content to the home.html.erb file:
<div class="container">
<h1>Private TODOs</h1>
<% if current_user %>
<%= link_to "Sign Out", destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to "Sign In", new_user_session_path %>
<%= link_to "Sign Up", new_user_registration_path %>
<% end %>
</div>
Let’s run our containers
> docker-compose up
Try going to http://localhost:3000/users/sign_up and try to register a user, then log in at http://localhost:3000/users/sign_in.
Now we have a user registered!
Look and Feel
Install Bootstrap 4 in Rails 6
Now we have a basic authentication dockerized rails app. Not so much, and also doesn’t look so good. So let’s add some styles
First of all, we will require the bootstrap gem, using yarn:
> docker-compose run web yarn add bootstrap jquery popper.js
Then inside webpack/environment.js (above module.exports directive), we will add these lines:
const webpack = require('webpack')
environment.plugins.append('Provide', new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
}))
Inside app/assets/stylesheets/application.css file, right above “*= require_tree”, we need to add:
*= require bootstrap
Inside assets/javascript/packs/ create a folder called “src”. In it, create a file called application.scss, and put these line inside:
@import "~bootstrap/scss/bootstrap";
Yes, we will use Sass, a CSS precompiler for our styles. Now we need also to require bootstrap in JS and CSS application files. In this regard, we will modify the file app/javascript/pack/application.js adding these lines at the bottom:
import "bootstrap";
import "./src/application.scss";
Great! We have Bootstrap 4 installed in our Rails 6 app! Let’s use it.
Generate Devise Views with Bootstrap 4
At this point, we have a dockerized Rails 6 application with authorization handled by Devise, and Boostrap 4 installed, but not yet used, so let’s get into it.
We will require a gem that handles all the basic layout views for Devise with Bootstrap 4 for us, by adding this line to our Gemfile:
# Gemfile
gem 'devise-i18n'
gem 'devise-bootstrap-views', '~> 1.0'
Now to bundle, we will rebuild our docker images (remember the build command will bundle install among other things. Then execute in terminal:
> docker-compose down
> docker-compose build
Now in the file app/assets/stylesheets/application.css, right above “*= require_tree .” put:
*= require devise_bootstrap_views
Now in a separate terminal, run this command to generate the bootstrap views for Devise:
> docker-compose run --rm web rails g devise:views:bootstrap_templates
It will modify all our current Devise views to use bootstrap, so accept all prompts. We can modify it at any time.
Now start our containers one more time and try again going to http://localhost:3000/users/sign_up and our styles should be there.
> docker-compose up
Wow! now we have some bootstrap styles without any coding, amazing! But it still looks weird, so I modified it in GitHub repo step-2 to get it centered.
The next step is to get our models with TDD, so you can continue to the next post if you need to. Don’t forget to clap is it was useful to you! Thanks!