【问题标题】:PG::UniqueViolation: ERROR: duplicate key value violates unique constraintPG::UniqueViolation:错误:重复键值违反唯一约束
【发布时间】:2016-09-15 13:44:16
【问题描述】:

我在 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"

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

schemafile

中的用户和个人资料表
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

【问题讨论】:

  • 将您的架构文件添加到问题中(位于db/schema.rb
  • 您是否尝试使用现有电子邮件注册?
  • 不,我正在更新现有用户详细信息(名字、姓氏等)
  • “当我运行我的应用程序时,会发生此错误。”--您需要告诉我们运行应用程序时正在运行的代码。您发布的任何代码都不足以导致该错误。很可能,您的应用程序代码只是试图插入两个具有相同电子邮件地址的用户。
  • 最大我需要覆盖用户表中的设计验证,用户表有嵌套属性(配置文件)。如果我创建一个新的用户配置文件,我需要验证密码字段,同时密码如果我编辑用户个人资料,该字段未验证...我希望它有助于理解我的问题

标签: ruby-on-rails devise


【解决方案1】:

查看您的test/fixtures/users.yml 文件并注释掉任何空白的灯具。请参见下面的示例:

#one: {}
#two: {}

【讨论】:

  • @xenetics 因为这是注释掉两个空白模型的定义,onetwo。如果模型在夹具中没有设置属性,则默认为 null。如果您对空行或重复行进行验证,则在为同一列插入两个空行时它将失败。
  • 这应该被赞成。一些生成器无法根据验证提供良好的固定装置。到目前为止,devise 就是一个例子。
  • 感谢您的提及,我现在知道问题是在这里发生的,因为我没有在fixtures/xxxx.yml 中创建完整的测试数据。
  • 这很好用。被严重低估的答案
【解决方案2】:

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

rake db:drop
rake db:create
rake db:migrate

希望它会起作用

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

      这意味着,如果您没有通过为每个电子邮件选择不同的电子邮件来使夹具记录不同,或者删除其中一个,您将收到唯一性约束错误。

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

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

          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 生成器中的错误,或者在这些模型被子分类后没有清理。

          【讨论】:

            【解决方案7】:

            我成功了

            $ 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;
            

            【讨论】:

              【解决方案8】:

              我在生成用户时使用了 devised,但在运行测试时出现此错误。 我刚刚在我的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 %>
              

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2018-05-14
                • 2021-02-11
                • 2015-03-24
                • 2020-02-15
                • 2016-07-27
                • 2011-10-17
                • 2012-03-03
                相关资源
                最近更新 更多