Доступ к методу модели из контроллера - PullRequest
0 голосов
/ 09 мая 2020

У меня есть форма входа с использованием gem bcrypt. Он работает, как ожидалось, в консоли рельсов. Однако я получаю эти ошибки на сайте. Любая помощь будет очень признательна.

NoMethodError в ManagersController # loginattempt undefined method `authentication 'for true: TrueClass

Я прочитал несколько сообщений SO - я использовал, внес исправления, которые они не разрешают ошибка:

Например - это потому, что класс аутентификации не имеет префикса '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 Ответ

1 голос
/ 09 мая 2020

Несколько замечаний:

  1. Manager.where(manager_params) является избыточным, потому что manager_params это что-то вроде {manager: {username: 'foo', password: 'password'}}, но where методы принимают простые ha sh как {username: 'foo', password: 'password'}.
  2. Вы можете и должны использовать find_by вместо where и exists?, потому что exists? возвращает логическое значение, а это не то, что вам нужно. find_by возвращает nil, если запись не существует.
  3. Manager#authenticate метод (authenticate метод экземпляра в Manager классе) принимает только пароль, поэтому вы можете использовать @manager.authenticate(params[:manager][:password]) вместо @manager.authenticate(manager_params)

Я хотел бы отметить, что если username уникален, мы можем найти пользователя только по username без пароля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...