首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Omniauth error - PG::Error: ERROR:重复键值违反

Omniauth error - PG::Error: ERROR:重复键值违反
EN

Stack Overflow用户
提问于 2013-08-09 07:30:09
回答 3查看 2.4K关注 0票数 2

因此,我帮助一位朋友将Omniauth添加到他的应用程序中,出于某种原因,omniauth只是第一次工作。

但现在,它又回来了

代码语言:javascript
复制
     PG::Error: ERROR: duplicate key value violates 
    unique constraint "index_users_on_email" 
DETAIL: Key (email)=() already exists. : INSERT INTO "users" 
("created_at", "provider", "uid", "updated_at", "username") 
VALUES ($1, $2, $3, $4, $5) RETURNING "id"

就好像它只接受一个,然后说“已经存在了”。我们怎样才能做到这一点?

user.rb

代码语言:javascript
复制
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :omniauthable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :songs
  has_many :comments

  acts_as_voter

  def self.from_omniauth(auth)
    where(auth.slice(:provider, :uid)).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.username = auth.info.nickname
    end
  end

  def self.new_with_session(params, session)
    if session["devise.user_attributes"]
      new session["devise.user_attributes"] do |user|
          user.attributes = params
        user.valid?
      end
    else
      super
    end
  end

  def password_required?
    super && provider.blank?
  end

  def update_with_password(params, *options)
    if encrypted_password.blank?
      update_attributes(params, *options)
    else
      super
    end
  end

  def email_required?
    super && provider.blank?
  end


end

模式片段

代码语言:javascript
复制
 create_table "users", force: true do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.boolean  "admin"
    t.string   "provider"
    t.string   "uid"
    t.string   "username"
  end

全i控制器

代码语言:javascript
复制
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def all
    user = User.from_omniauth(request.env["omniauth.auth"])
    if user.persisted?
      flash.notice = "Signed in!"
      sign_in_and_redirect user
    else
      session["devise.user_attributes"] = user.attributes
      redirect_to new_user_registration_url
    end
  end
  alias_method :twitter, :all
end

所有访问键都按照栏杆上最新的ep适当设置。

EN

回答 3

Stack Overflow用户

发布于 2013-08-09 07:40:47

您对电子邮件字段有一个唯一的限制。因为此字段被定义为不可空,并且默认值为"“(空字符串)。这意味着如果不指定电子邮件,DBMS将将此字段设置为"“。当然,因为它有一个唯一的约束,所以您只能在没有电子邮件的情况下添加两个用户,因为只有一个用户可以拥有空的字符串电子邮件。

如果您没有手动创建约束,那么我假设rails已经为您创建了约束(因为电子邮件字段上显然有一个索引),方法是假设第一个字段是表主键,因为您没有指定任何字段。这使得它既创建了索引,也对其创建了唯一的约束。

票数 2
EN

Stack Overflow用户

发布于 2014-01-14 15:47:01

一个更简单的解释可能是,这是由于您的测试数据生成没有唯一的电子邮件。如果您看到以下内容,请尝试查看/test/like/users.yml:

代码语言:javascript
复制
one: {
}
two: {
}

然后将其更改为

代码语言:javascript
复制
one: {
  email: tester1@stack.com
}
one: {
  email: tester2@stack.com
}

或者您可以删除文件的内容。

票数 2
EN

Stack Overflow用户

发布于 2014-10-02 10:00:42

您可以从电子邮件中删除索引,因为设计将其设置为唯一。你不能有重复的空白电子邮件地址,根据设计如何设置默认设置。下面是一个迁移示例。

代码语言:javascript
复制
class ChangeEmail < ActiveRecord::Migration
  def change
    remove_index :users, :email
  end
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18141996

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档