Welcome back and thank you for reading! In this tutorial, we will install devise and create the user and post model. We will also set up emails in production with the Heroku Sendgrid addon.

Finally, we will create the relationship between users and posts.

Let’s begin by installing the devise gem

# Add devise to your gemfile
gem devise
bundle install
rails g devise:install
# Open config/environments/development.rb and add:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } 
# For production we are going to use Sendgrid to send emails. Sendgrid is a free Heroku addon, however you will need to add a credit card to your Heroku account for this to work.
# Open config/environments/production.rb and add: 
config.action_mailer.default_url_options = { host: 'https://www.mirrorcommunications.com' } # change this to your heroku domain or your custom domain.
  config.action_mailer.delivery_method = :smtp
    ActionMailer::Base.smtp_settings = {
    :user_name => ENV['SENDGRID_USERNAME'],
    :password =>  ENV['SENDGRID_PASSWORD'],
    :domain => 'mirrorcommunications.com', # change this to your heroku domain, or your custom domain.
    :address => 'smtp.sendgrid.net',
    :port => 587,
    :authentication => :plain,
    :enable_starttls_auto => true

Now lets add Sendgrid to send emails in production

# In the terminal run:
heroku addons:create sendgrid:starter
heroku config:get SENDGRID_USERNAME
# Copy the output and save it to a file.
heroku config:get SENDGRID_PASSWORD
# Copy the output and save it as well.
# Now login to Sendgrid and create an api key: https://app.sendgrid.com/settings/api_keys
# Copy your api key and add it to heroku with:
heroku config:set SENDGRID_API_KEY=xxxx_your_key_xxxx # paste in your key.
# Check that it worked with: 
heroku config
SENDGRID_API_KEY: xxxx_api_key_xxxx
OTHER_VAR: production
# That’s it, you are ready to receive emails in production!

Next let’s add devise alerts and notices to our app

# In app/views/layouts create
# Now paste in and save:
<% if notice %>
  <%= notice %>
<% end %>
<% if alert %>
  <%= alert %>
<% end %>
# Now open app/views/layouts/application.html.erb add the devise notices partial. Add it above the yield tag, and between the body tags.
  <%= render 'layouts/devise_notices' %>
   <%= yield %>

Now we need to define a root path

let’s do that by creating our models:

# First let’s create our Users model with:
rails g devise User first_name last_name about:text img role:integer
# Now let’s create our Posts model with a scaffold:
rails g scaffold Post titletag meta:text cover_image title body:text user:references
# Before we run rails db:migrate, let’s open the devise migration file and uncomment the lockable function:
  ## Lockable
      t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      t.string   :unlock_token # Only if unlock strategy is :email or :both
      t.datetime :locked_at
# You don’t have to do this but it is likely a feature you will want in the future.
rails db:migrate
# Now open app/models/post and make sure it has:
belongs_to :user
# Also open the user model and add:
has_many :posts

Updating the Posts Controller

Now we need to update the post create action in the posts controller, so that posts are created by users.

# app/controllers/posts_controller.rb change this line in the create action:
def create
  @post = Post.new(post_params)
# To this:
def create
  @post = current_user.posts.build(post_params)

Next, create the devise views

rails g devise:views

Let’s now finish the devise install by defining a route path

# config/routes.rb add:
devise_for :users, except: :create, path: '', path_names: { sign_in: 'login', sign_out: 'signed-out' }
# This creates pretty devise links... 
# You will also notice that I added except: :create which means that we are not going to allow public signups. 
# This is because I only want existing admins to be able to create new users. We will set this up later...
resources :posts
root to: 'posts#index'

Create the Sign-out Page

Let's now create the sign-out page we identified in our devise route above.

rails g controller Signouts index
# routes.rb
get 'signed-out', to: 'signouts#index'
# Open views/signouts/index and add
<h2>Signed Out!</h2>

We have now installed everything we need for devise, our next step is to completely customize it for our needs.

Note: Don't add any users just yet as we will be using the friendly_id gem to display user names in our urls.

Let’s save our work and push it to Github and Heroku.

git add .
git commit -m installed devise and set up sendgrid for emails
git push origin master
git push heroku master # You can skip this step for now if you don't want anyone to be able to sign up publicly.
heroku run rails db:migrate
Click here to view part 3. Or click here to go back to part 1.