gqli
gqli

Reputation: 1045

How to understand authenticated?(:activation, params[:id]) in rails 4?

I am reading Michael Hartl's rails tutorial and i couldn't understand this line at chapter 10 authenticated?(:activation, params[:id])

According to the author this line is used to compare the activation_digest and the token This implicates that the token will be available at params[:id]

This is where i get confused . Does params[:id] retrieve user's ID how can they compare ID with activation_digest?

However authenticated?(:remember, cookies[:remember_token]) makes perfect sense to me. Anyone ? Your help will be very much appreciated!

The related code is shown on below :

account_activations_controller.rb

class AccountActivationsController < ApplicationController
    def edit
    user = User.find_by(email: params[:email])
    if user && !user.activated? && user.authenticated?(:activation, params[:id])
      user.activate
      log_in user
      flash[:success] = "Account activated!"
      redirect_to user
    else
      flash[:danger] = "Invalid activation link"
      redirect_to root_url
    end
  end
end

routes.rb

Rails.application.routes.draw do
  get 'password_resets/new'

  get 'password_resets/edit'

  get 'sessions/new'

  get 'users/new'

  root             'static_pages#home'
  get 'help'    => 'static_pages#help'
  get 'about'   => 'static_pages#about'
  get 'contact' => 'static_pages#contact'
  get 'signup'  => 'users#new'
  get    'login'   => 'sessions#new'
  post   'login'   => 'sessions#create'
  delete 'logout'  => 'sessions#destroy'
  resources :users
  resources :account_activations, only: [:edit]
  resources :password_resets,     only: [:new, :create, :edit, :update]

User.rb

class User < ActiveRecord::Base
    attr_accessor :remember_token, :activation_token, :reset_token
  before_save   :downcase_email
    before_create :create_activation_digest
    validates :name,   presence: true, length: { maximum: 50 }
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
    validates :email,  presence: true, length: { maximum: 255 },
                       format: { with: VALID_EMAIL_REGEX },
                       uniqueness: { case_sensitive: false }
    has_secure_password
    validates :password, length: { minimum:6 }, allow_blank: true

class << self
    # Returns the hash digest of the given string.
  def digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

    # Returns a random token.
  def new_token
    SecureRandom.urlsafe_base64
  end
end

  # Remembers a user in the database for use in persistent sessions.
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

  # Returns true if the given token matches the digest.
  def authenticated?(remember_token)
    return false if remember_digest.nil?
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end

  # Returns true if the given token matches the digest.
  def authenticated?(attribute, token)
    digest = send("#{attribute}_digest")
    return false if digest.nil?
    BCrypt::Password.new(digest).is_password?(token)
  end

  # Forgets a user.
  def forget
    update_attribute(:remember_digest, nil)
  end

  # Activates an account.
  def activate
    update_attribute(:activated,    true)
    update_attribute(:activated_at, Time.zone.now)
  end

  # Sends activation email.
  def send_activation_email
    UserMailer.account_activation(self).deliver_now
  end

  # Sets the password reset attributes.
  def create_reset_digest
    self.reset_token = User.new_token
    update_attribute(:reset_digest,  User.digest(reset_token))
    update_attribute(:reset_sent_at, Time.zone.now)
  end

  # Sends password reset email.
  def send_password_reset_email
    UserMailer.password_reset(self).deliver_now
  end

private
# Converts email to all lower-case.
def downcase_email
  self.email = email.downcase
end

# Creates and assigns the activation token and digest.
def create_activation_digest
  self.activation_token  = User.new_token
  self.activation_digest = User.digest(activation_token)
 end
end

Upvotes: 1

Views: 887

Answers (1)

gqli
gqli

Reputation: 1045

I post it on ruby on rails talk on google, Finally someone has answered my question. For those are reading Michael Hartl's book, you might find this useful.

Anyway, the whole point of params[:id] is related to routes.rb file which indicates that it has something to do with the url that generated by routes. in this case . I'm using RESTful urls in rails

let's say if the URL is : https://www.examples.com/account_activations/token_fFb_F94mgQtmlSvRFGsITw/edit?email=michael%40michaelhartl.com

then params[:id] would be "token_fFb_F94mgQtmlSvRFGsITw"

Better explanation can be found here Click here to check

My issue was i mistaken the ":id" in params[:id] as the numerical id attribute in the user table. Hope you will not make the same mistake as i did. Good luck !

Upvotes: 1

Related Questions