设计 - 通过电子邮件或用户名登录

时间:2015-10-27 12:45:00

标签: ruby-on-rails ruby-on-rails-4 devise

我已完成本教程的所有内容:Devise wiki

但是当我尝试登录时,我在浏览器中收到错误:

SQLite3::SQLException: no such column: users.login: SELECT "users".* FROM "users" WHERE "users"."login" = 'jan12345' ORDER BY "users"."id" ASC LIMIT 1

哪里可能有问题?如何调试?

login表上没有users字段,但我有username字段。

我的模特档案:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  attr_accessor :login
  protect_from_forgery with: :exception

  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :expiration_date) }
    devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :username, :email, :password, :remember_me) }
  end
end

3 个答案:

答案 0 :(得分:2)

您正在向数据库发送login属性;您需要将usernameemail设为自定义属性和自定义属性的组合。特殊查找,as per the docs

#app/models/user.rb
class User < ActiveRecord::Base
  #remove attr_accessor :login (it just makes getter/setter methods which we do manually below)

  protected

  def login=(login)
    @login = login
  end

  def login
    @login || self.username || self.email
  end

  private

  def self.find_for_database_authentication(warden_conditions)
      conditions = warden_conditions.dup
      if login = conditions.delete(:login)
         where(conditions.to_h).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
      else
         where(conditions.to_h).first
      end
  end
end

-

你在使用消毒杀菌剂等方面表现非常出色 - 你正在做的是采取一个“登录”属性&amp;使Devise使用 loginusernameemail来查找User记录。

目前,错误显示无法找到users.login - 这意味着您的Devise安装正在查找login(不在您的数据库中),应该是使用username属性搜索emaillogin

第二位代码(self.find_for_database_authentication)执行Devise的查找。如果您阅读了该查询,则需要login 属性并将其设置为 <{em> usernameemail。您的实施中缺少这个,应该添加。

添加后,请记住重新启动服务器。

<强>更新

您的attr_accessor应该在模型中(您的模型)。

它所做的就是为您定义的属性定义settergetter方法。它通常被称为"virtual" attribute,因为它没有保存在数据库中。

如果需要,我可以告诉你有关setter / getter种方法的信息,我现在就把它留下以防止混淆

答案 1 :(得分:0)

在初始化程序/ devise.rb中,编写以下代码:

config.authentication_keys = [:username]

在应用程序控制器中,编写以下代码:

 def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username) }
    devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username) }
 end

答案 2 :(得分:0)

您不必做那么多代码,

您可以从https://stackoverflow.com/a/55184048/9490901

进行检查

仅将contact_number替换为用户名: