Tuesday, December 9, 2014

Creating user model

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

No comments:

Post a Comment