Search code examples
ruby-on-railsstrong-parametersupdate-attribute

update_attribute with error undefined method `update_attribute' for #<Class


The specific code below from the book using Rails 4 I believed in rails 5 required strong parameters that may cause error in Rails 5. Please anyone could share me. How to apply permit and require for the following code)

From model user.rb

def remember
    remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
end

error (in rails 5)

NoMethodError in SessionsController#create
undefined method `update_attribute' for #<Class

Here what I did.

def remember
    remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(params:[remember_token]))
end

error:

NoMethodError in SessionsController#create
undefined method `update_attribute' for #<Class:0x007fd23b30a790> Did you mean? _default_attributes

Tobe clear: those method called from sessionshelper.erb

module SessionsHelper

  # Logs in the given user.
  def log_in(user)
    session[:user_id] = user.id
  end

  # Remembers a user in a persistent session.
  def remember(user)
    User.remember
    cookies.permanent.signed[:user_id] = user.id
    cookies.permanent[:remember_token] = user.remember_token
  end


    # Returns the user corresponding to the remember token cookie.
  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end


  # Returns true if the user is logged in, false otherwise.
  def logged_in?
    !current_user.nil?
  end

# Forgets a persistent session.
  def forget(user)
    user.forget
    cookies.delete(:user_id)
    cookies.delete(:remember_token)
  end
  # Logs out the current user.
  def log_out
    forget(current_user)
    session.delete(:user_id)
    @current_user = nil
  end
end

user.rb

class User < ApplicationRecord
  attr_accessor :remember_token, :activation_token, :reset_token, :remember_digest
  before_save { self.email = email.downcase }
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[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, presence: true, length: { minimum: 6 }
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

  def remember
    remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end



  # Returns a random token.
  def new_token
    SecureRandom.urlsafe_base64
  end
end
  # Returns true if the given token matches the digest.
  def authenticated?(remember_token)
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end
  # Forgets a user.
  def forget
    update_attribute(:remember_digest, nil)
  end

  def activate
    update_attribute(:activated,    true)
    update_attribute(:activated_at, Time.zone.now)
  end

end

sessionscontroller.rb

class SessionsController < ApplicationController

  def new
  end

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      remember user
      redirect_to user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    log_out
    redirect_to url_for(:controller => :sessions, :action => :new)  
  end
end

Eooro


Solution

  • The issue is in the helper, the line

    You are calling the remember method with the User class, so it is showing undefined method for class. Instead call with user object

    User.remember

    should be,

    user.remember

    def remember(user)
        user.remember
        cookies.permanent.signed[:user_id] = user.id
        cookies.permanent[:remember_token] = user.remember_token
    end