PG :: UniqueViolation:ERROR:重复键值违反唯一约束

时间:2016-09-15 13:44:17

标签: ruby-on-rails devise

我在rails(4.2.6)中使用devise(4.2.0)。

在我的应用程序中,我在用户和配置文件表中使用嵌套属性。我只有在创建新记录时才需要验证密码,在更新创建的记录时未验证密码字段。

我的 user.rb 文件是:

class User < ActiveRecord::Base
 has_one :profile
 has_one :company_profile
 accepts_nested_attributes_for :profile
 attr_accessor :profile_updation


 devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable

 validates_presence_of :email, if: :email_required?


 validates_presence_of :password, if: :password_required?
 validates_confirmation_of :password, if: :password_required?

 protected

 def email_required?
   true && profile_updation.blank?
 end

 def password_required?
   !password.nil? || !password_confirmation.nil?

 end

end

当我运行我的应用程序时,发生了这个错误:

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_email" DETAIL: Key (email)=() already exists. : INSERT INTO "users" ("first_name", "last_name", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"

我搜索了这个问题,但我无法解决。

用户&amp; 架构文件

中的配置文件表
create_table "users", force: :cascade 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,  null: false
   t.datetime "current_sign_in_at"
   t.datetime "last_sign_in_at"
   t.inet     "current_sign_in_ip"
   t.inet     "last_sign_in_ip"
   t.datetime "created_at",                          null: false
   t.datetime "updated_at",                          null: false
   t.string   "first_name"
   t.string   "last_name"
   t.string   "user_id"
 end

 add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
 add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree        
 add_index "profiles", ["user_id"], name: "index_profiles_on_user_id", using: :btree

create_table "profiles", force: :cascade do |t|
   t.string   "company_name"
   t.integer  "country"
   t.integer  "state"
   t.integer  "business"
   t.string   "mobile_no"
   t.datetime "created_at",       null: false
   t.datetime "updated_at",       null: false
   t.integer  "user_id"
   t.boolean  "terms_conditions"
 end

8 个答案:

答案 0 :(得分:16)

看看你的test / fixtures / users.yml文件并注释掉任何空白的灯具。见下面的例子:

init_pm

答案 1 :(得分:7)

我也面临同样的问题, 删除数据库并重新创建它。

&#13;
&#13;
rake db:drop
rake db:create
rake db:migrate
&#13;
&#13;
&#13;

希望它能运作

答案 2 :(得分:3)

您正在插入没有电子邮件的用户,而您已有一个用户。如果要忽略重复检查的空白,请更改验证器:

class User < ActiveRecord::Base
  validates :email, :uniqueness => {:allow_blank => true}
end

答案 3 :(得分:0)

执行了Devise的所有设置步骤后,有两件事是正确的:

  1. 在夹具中为用户模型测试定义了两个用户,onetwo。这些用户是空的。它们没有任何属性的值。
  2. 您的db/schema.rb文件中的email表的users列有唯一性约束。如果要保留现有用户中已经包含电子邮件的用户,则数据库将引发错误。

这意味着如果您没有通过为每个灯具选择不同的电子邮件来使灯具记录有所不同,或者删除其中一封,则会出现唯一性约束错误。

答案 4 :(得分:0)

我独特的特殊雪花问题是我有多态模型,并且有多个夹具,它们具有不同的模型名称,但是它们继承自同一张表。

class Student < User
class ContentCreator < User
class Admin < User
class User < ActiveRecord::Base
  def admin
    self.type == "Admin"
  end
  def student
    self.type == "Student"
  end
  ...

因此,即使我在user.yml中只有一个条目,在其他文件中,例如students.yml还是有多个条目

one: {}
# column: value    
two: {}
#  column: value

这可能是rails生成器中的一个错误,否则在对这些模型进行子分类之后就没有将其清除。

答案 5 :(得分:0)

在某些情况下,您导入Postgres DB,也许删除数据库不是一个好的解决方案,并且您需要数据,所以可以使用以下psql命令更改seq字段:

ALTER SEQUENCE $sequence_name RESTART WITH $ID;
* ID is a start value of $sequence_name

答案 6 :(得分:0)

我成功了

$ CREATE SEQUENCE roles_id_seq;
$ ALTER TABLE roles ALTER COLUMN id SET DEFAULT nextval('roles_id_seq'::regclass);
$ ALTER SEQUENCE roles_id_seq OWNED BY roles.id;

答案 7 :(得分:0)

我使用了devise来生成用户,并且在运行测试时遇到此错误。 我刚刚在tests/fixtures/users.yml文件中添加了以下内容。

admin:
  id: 1
  email: admin@testmail.com
  encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>
  created_at: <%= Time.zone.now %>

staff:
  id: 2
  email: staff@testmail.com
  encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>
  created_at: <%= Time.zone.now %>

现在,我的测试工作正常。