I'm going to start by creating a model for users, using devise for authentication.
Do give the GitHub page a read to get some idea on devise. I'm mostly just going to be following the Getting Started section here.
To install devise, put the gem in the Gemfile,
gem 'devise'
and then use
rails generate devise:install
rails generate devise User
The installer is going to ask you to set up the mailer, which I will do at the end of this blog post.
The next thing to do is to check the generated app/models/user.rb and migration file, and make any changes that
you think is necessary.
I'm happy to just use the default User model generated by devise.
For this application, I'm going to use
class User < ActiveRecord::Base
devise :database_authenticatable,
:registerable, :confirmable,
:lockable, :recoverable,
:rememberable, :trackable, :validatable
For the migration file (inside db/migrate), I uncommented the variables
for lockable and confirmable.
Creating a welcome page
I'm going to need a welcome page to test out devise, so let's make one quickly using
rails generate controller StaticPages start
which is going to create start.html in the app/views/static_pages directory.
When I started coding with rails, I didn't know why you would refer to an html as a static page.
Michael Hartl, for one, talked about
"mostly static pages". Back then I thought every page
was static. After all, aren't websites simply a collection of htmls?
After some time learning about rails, and more generally about MVC (Model View Controller) framework, I understand now that a rails app focuses on the models.
If we generate a model using scaffolding, rails will automatically generate several html pages,
or views, to let us interact with the model. For example, it will create an index.html page
that lists every instance of a model.
Most of these pages would be dynamically created based on the information stored in the database.
So an html page which shows a welcome message and login/password box is pretty static in comparison.
It seems like a good idea to group all the static pages that you're going to write under one
controller, because they mostly behave in the same way. This is what I did above, using the
StaticPages controller.
It is possible to set up a master layout for all pages under one controller in rails:
inside the app/views/layouts directory, put an html (or html.erb) file
with the same name as the model.
I'm going to be using slim, so it's
.html.slim from here on. The master layout for all StaticPages views can be placed in
app/views/layouts/static_pages.html.slim
You can also put the layout inside application.html.slim
which becomes the fallback layout file, i.e. it will be used if an html
with the same name as the model is not found.
You can do more complicated things involving layouts inside the controller; check the
rails guides.
I put the following code inside static_pages.html
doctype html
html
head
title "Insert title"
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
= javascript_include_tag 'application', 'data-turbolinks-track' => true
= csrf_meta_tags
.container style="text-align: right"
- if user_signed_in?
h5 Logged in as #{current_user.username} | #{link_to "Log out", destroy_user_session_path, method: :delete}
- else
= link_to "Log in", new_user_session_path
body
.container
= yield
Notice how it already contains several devise helpers, like current_user, user_signed_in?, etc.
Setting up the mailer
Devise provides a login page, namely new_user_session_path, where a user can also
sign up by providing an email and password. As usual, an email is then sent to the user's email
address to confirm its authenticity by providing a confirmation link.
For this system to work, we must set up a mail system in our development environment.
I use MockSMTP.
MockSMTP provides a local SMTP server using port 1025. Once it is installed (it is
a paid app by the way), add the following codes to config/environments/developmentr.rb
config.action_mailer.default_url_options = {:host => 'localhost:3000'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {:address => "localhost", :port => 1025}
Registration by email should work properly. If you try to sign up, an email will be generated
and sent to your MockSMTP mailbox, from where you can access the confirmation link.
To see the page locally, we need to run both db:create and db:migrate