设计错误,SQLite3 :: ConstraintException:UNIQUE约束失败:users.email

时间:2015-12-06 10:17:23

标签: ruby-on-rails devise

我正在关注source code以使用户使用他们的电子邮件或用户名登录。 但是我得到了这样的错误。 this wiki

我该如何解决? 我的应用程序控制器是

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

  skip_before_filter :verify_authenticity_token

  after_filter :store_location

  before_action :configure_permitted_parameters, if: :devise_controller?

  def store_location
    # store last url - this is needed for post-login redirect to whatever the user last visited.
    return unless request.get? 
    if (request.path != "/users/sign_in" &&
        request.path != "/users/sign_up" &&
        request.path != "/users/password/new" &&
        request.path != "/users/password/edit" &&
        request.path != "/users/confirmation" &&
        request.path != "/users/sign_out" &&
        !request.xhr?) # don't store ajax calls
      session[:previous_url] = request.fullpath 
    end
  end

  def after_sign_in_path_for(resource)
    session[:previous_url] || root_path
  end

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :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(:username, :email, :password, :password_confirmation, :current_password) }
  end

end

我的models/user.rb看起来像

class User < ActiveRecord::Base
  has_many :hasuk_houses, dependent: :destroy
  has_many :favorite_hasuk_houses
  has_many :favorites, through: :favorite_hasuk_houses, source: :hasuk_house


  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable,
         :omniauthable, :omniauth_providers => [:facebook]
  devise :validatable, :authentication_keys => [:login]

  attr_accessor :login

  validate :validate_username

  def validate_username
    if User.where(email: username).exists?
      errors.add(:username, :invalid)
    end
  end

  def email_required?
    false
  end

  def login=(login)
    @login = login
  end

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


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


  #facebook login
  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.email = auth.info.email
      user.password = Devise.friendly_token[0,20]
      user.name = auth.info.name   # assuming the user model has a name
    end
  end

  def self.new_with_session(params, session)
    super.tap do |user|
      if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
        user.email = data["email"] if user.email.blank?
      end
    end
  end

end

1 个答案:

答案 0 :(得分:1)

您所遇到的错误是因为您输入的电子邮件已用于数据库中的其他用户。

现在,这是一个唯一性验证错误,当尝试使用唯一性验证集复制列时会出现问题。

有不同级别的验证,有模型验证,您可以在模型中设置,并由Rails管理,并且有数据库级验证。

以上是数据库级验证的示例。

在这种情况下,您可以做的是在用户模型中设置相应的模型级别验证:

#user.rb:
class User < ActiveRecord::Base
  ...
  validates :email, uniqueness: true
  ...
end

这将提供另一级别的验证,该控制将由应用程序触发,并由应用程序处理,然后才能控制数据库。

您现在可以随时处理此验证。