设计:尝试设置用户名字段

时间:2014-06-19 05:21:49

标签: ruby-on-rails postgresql devise

我正在尝试使用此tutoral设置一个用户名字段:https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address

当登录和所有内容时,登录字段工作正常,但当我尝试重置密码或重新发送确认消息时,我收到了postgres的错误:

PG::UndefinedColumn: ERROR: column users.login does not exist LINE 1: SELECT "users".*      FROM "users" WHERE "users"."login" = 'nah... ^ : SELECT "users".* FROM "users" WHERE "users"."login" = 'nahtnam' ORDER BY "users"."id" ASC LIMIT 1

这是我的application_controller.rb:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_filter :configure_permitted_parameters, if: :devise_controller?
  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:firstname, :lastname, :username, :email, :password, :password_confirmation, :birthdate, :remember_me) }
    devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :username, :email, :password, :remember_me) }
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:firstname, :lastname, :email, :password, :password_confirmation, :current_password) }
  end
end

这是我的users.rb模型:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable, :lockable, :timeoutable, :omniauthable,
         :authentication_keys => [:login]
  attr_accessor :login
  validates :username, :presence => true, :uniqueness => true
  validates :firstname, :presence => true
  validates :lastname, :presence => true
  def self.find_for_database_authentication(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:login)
      where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
    else
      where(conditions).first
    end
  end
end

我认为我也正确设置了配置。

我不知道什么是错的。我尝试将attr_accessor移到devise :database_authenticatable, :registerable之上,但这并没有真正帮助。

问题是我在另一个应用程序上100%工作,它只是不起作用! :(

感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

修正了它!

我改变了这一部分:

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

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

self.find_for_database_authentication更改为self.find_first_by_auth_conditions

答案 1 :(得分:2)

埋在bottom of the wiki you linked它表示您需要将以下内容添加到config/initializers/devise.rb文件中以“配置设置以使用登录作为重置密码或确认密钥”:

config.reset_password_keys = [ :login ]
config.confirmation_keys = [ :login ]

另外请务必更新您的观点。在passwords/new.html.erb删除:

<p><%= f.label :email %><br />
<%= f.text_field :email %></p>

并添加:

<p><%= f.label :login %><br />
<%= f.text_field :login %></p>

confirmations/new.html.erb中,删除:

<p><%= f.label :email %><br />
<%= f.email_field :email %></p>

并添加:

<p><%= f.label :login %><br />
<%= f.text_field :login %></p>