从控制器访问模型方法

时间:2020-05-09 16:48:56

标签: ruby-on-rails

我有一个使用bcrypt gem的登录表单。它在rails控制台中按预期工作。但是,我在网站上收到这些错误。非常感激任何的帮助。

ManagersController#login中的NoMethodError尝试将未定义的方法“验证”为true:TrueClass

我已经阅读了几篇SO帖子-我使用过一些修正,但无法解决错误:

例如-这是因为authenticate类没有前缀“ self”,所以该建议实际上破坏了终端@some_user.authenticate('***********') => true的工作功能

    def authenticate(password)
        self.password_hash == BCrypt::Engine.hash_secret(password, password_salt)
    end
or

    def self.authenticate(password)
        self.password_hash == BCrypt::Engine.hash_secret(password, password_salt)
    end

or
    def self.authenticate(password)
        password_hash == BCrypt::Engine.hash_secret(password, password_salt)
    end

型号

class Manager < ApplicationRecord
    attr_accessor :password

    validates :username, presence: true, uniqueness: true
    validates :password, presence: true, on: :create


    before_validation(on: :create) do
        encrypt_password
    end

    def authenticate(password)
        password_hash == BCrypt::Engine.hash_secret(password, password_salt)
    end

    private 
        def encrypt_password
            self.password_salt = BCrypt::Engine.generate_salt
            self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
        end
end

控制器-会产生错误。

class ManagersController < ApplicationController
    ...
    def loginattempt
        @manager = Manager.where(manager_params).exists?
        if @manager && @manager.authenticate(manager_params)
            redirect_to managers_path, notice: 'You are logged in.'
        else  
            redirect_to manager_login_path, notice: 'Username or Password incorrect.'
        end   
    end

    private
        def manager_params
            params.require(:manager).permit(:username, :password)
        end
end

为后代 我相信它现在可以按预期运行了-感谢SO社区在我需要帮助的时候为我提供帮助。 工作控制器

    def loginattempt
        @manager = Manager.find_by_username(manager_params[:username])
        if @manager.present? && @manager.authenticate(manager_params[:password])
            redirect_to manager_logged_in_path(@manager), notice: 'Logged In.'
            session[:logged_in] = @manager.id
        else  
            redirect_to manager_login_path, notice: 'Username or Password incorrect.'
        end
    end

1 个答案:

答案 0 :(得分:1)

一些注意事项:

  1. Manager.where(manager_params)是多余的,因为manager_params类似于{manager: {username: 'foo', password: 'password'}},但是where方法采用像{username: 'foo', password: 'password'}这样的简单哈希。
  2. 您可以并且应该使用find_by而不是whereexists?,因为exists?返回布尔值,这不是您想要的。如果记录不存在,find_by返回nil。
  3. Manager#authenticate方法(authenticate类的Manager实例方法)仅需要密码,因此您可以使用@manager.authenticate(params[:manager][:password])代替@manager.authenticate(manager_params)

我想提到的是,如果username是唯一的,我们只能通过username来找到用户,而无需输入密码。

相关问题