Skip to content
Evan Prothro edited this page Feb 5, 2014 · 10 revisions

Overview

Tutorial

Configure devise

  • Create the initializer file with rails generate devise:install
  • Search through config/initializers/devise.rb to make the following changes (if desired):
  # we configure sender using a BaseMailer#default(from: '[email protected]')
  # since we use our own mailer classes
  # config.mailer_sender = '[email protected]'

  # we override mailer classes on the models themselves
  # to have easier control over the mailer views and synchronicity of sending
  # config.mailer = 'Devise::Mailer'

  # 6 digit passwords aren't less secure than 8 just by definition
  config.password_length = 6..128
  
  # Allow sign_out via :get for easier dev and testing
  config.sign_out_via = :get
  • Ensure you have root_path defined (see your application routes), this is used as the default after sign-in path.

Create your User model

  • Create your model with rails g model user name:string
  • Add a to_s method
  def to_s
    self.name || self.email
  end

Extend your User model with Devise

  • Create the devise fields and set up the default modules rails g devise User && rake db:migrate

Create Haml views

rails g devise:views users

  • Convert ERB to Haml gem install html2haml for file in app/views/users/**/*.erb; do html2haml -e $file ${file%erb}haml && rm $file; done

Move views to the right location

  • Move the views/users/** directories to views/** to keep with the Rails convention

Make devise controllers explicit

  • Add the following controllers to app/controllers/(name)_controller.rb
class PasswordsController < ::Devise::PasswordsController
end
class RegistrationsController < ::Devise::RegistrationsController
end
class SessionsController < ::Devise::SessionsController
end
  • Point devise routes at those controllers by modifying config/routes.rb
devise_for :users, controllers: { registrations: "registrations",
                                    sessions: "sessions",
                                    passwords: "passwords" }

Use your own mailers

  • Add the following to your user model
  protected
    def devise_mailer
      UserMailer
    end
  • Create a UserMailer at mailers/user_mailer.rb
class UserMailer < BaseMailer

  def setup_account_instructions(user, opts={})
    @user = user
    secure_params = {user_id: user.id}
    @link_params = {data: UrlStore.encode(secure_params)}

    mail(to: user.email, subject: t('user.setup.instructions_email_subject'))
  end

  def confirmation_instructions(user, token, opts={})
    @token = token
    @user = user
    mail(to: user.email, subject: t('user.confirmation.instructions_email_subject'), opts)
  end

  def reset_password_instructions(user, token, opts={})
    @user = user
    @token = token

    mail(to: user.email, subject: t('user.password_change.instructions_email_subject'))
  end

end
* Rename the `views/mailers` views directory to `views/user_mailers` to keep with Rails conventions
  • If you don't have a base mailer, create one at app/mailers/base_mailer.rb
class BaseMailer < ActionMailer::Base
  default from: ENV["NO_REPLY_EMAIL_ADDRESS"] || "[email protected]"
end

Modify your nav to allow sign in/out

%header
  %nav.top-bar{"data-topbar" => true}
    %ul.title-area
      %li.name
        %h1= link_to Rails.application.class.parent_name.titleize, root_path
    %section.top-bar-section
      %ul.right
        - if current_user.present?
          %li.has-dropdown
            %a
              = current_user
            %ul.dropdown
              %li= link_to 'Settings', edit_user_registration_path
              %li= link_to 'Sign Out', destroy_user_session_path
        - else
          %li.active
            = link_to 'Sign In', new_user_session_path

Next Steps

Create some authenticated actions

Use before_filter :authenticate_user! for controller actions that require an authenticated user.

Don't be afraid to do things yourself

Often to get the behavior you want, it takes diving into Devise source to understand how their source works and then copying their source and overriding just the parts you want. Try to remember that Devise is extending your modeling, not locking it in.

Often, commenting out Devise modules (in the model), or skipping Devise routing modules (in routes.rb) and creating your own controllers is a more efficient method than figuring out how to 'correctly' bend Devise to your will.

Create User Avatars

See how to Create user avatars in a separate tutorial.