关于rails上的ruby:为什么PG :: UniqueViolation:ERROR:重复键值违反了唯一约束?

why PG::UniqueViolation: ERROR: duplicate key value violates unique constraint?

我有一个模型Post,每次创建一个帖子我想要同时创建一个新的Moderation实例。

所以在post.rb中我使用了回调after_save :create_moderation
然后写一个私有方法:

1
2
3
4
5
6
7
8
 ...
 include Reportable
 after_save :create_moderation

 private
 def create_moderation
    self.create_moderation!(blog: Blog.first)
 end

但是当创建提案时,我收到此错误:

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint"moderations_reportable" DETAIL: Key (reportable_type, reportable_id)=(Post, 25) already exists. : INSERT INTO"moderations" ("blog_id","reportable_type","reportable_id","created_at","updated_at","blog_type") VALUES ($1, $2, $3, $4, $5, $6) RETURNING"id"

在reportable.rb我有:

1
  has_one :moderation, as: :reportable, foreign_key:"reportable_id", foreign_type:"reportable_type", class_name:"Moderation"

然后很少有其他方法可报告对象。

请注意,当我在控制台中运行create方法时,不会发生此问题。

编辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  create_table"moderations", id: :serial, force: :cascade do |t|
    t.string"reportable_type", null: false
    t.string"reportable_id", null: false
    t.integer"blog_id", null: false
    t.datetime"created_at", null: false
    t.datetime"updated_at", null: false
    t.string"blog_type", null: false
    t.string"upstream_moderation", default:"unmoderate"
    t.index ["blog_id","blog_type"], name:"moderations_blog"
    t.index ["reportable_type","reportable_id"], name:"moderations_reportable", unique: true
  end



create_table"posts", id: :serial, force: :cascade do |t|
    t.text"title", null: false
    t.text"body", null: false
    t.integer"feature_id", null: false
    t.integer"author_id"
    t.integer"scope_id"
    t.datetime"created_at", null: false
    t.datetime"updated_at", null: false
    t.integer"post_votes_count", default: 0, null: false
    t.index ["body"], name:"post_body_search"
    t.index ["created_at"], name:"index_posts_on_created_at"
    t.index ["author_id"], name:"index_posts_on_author_id"
    t.index ["feature_id"], name:"index_posts_on_feature_id"
    t.index ["proposal_votes_count"], name:"index_posts_on_post_votes_count"
    t.index ["title"], name:"post_title_search"
  end


要解决这个问题,我们必须告诉ActiveRecord查看表的顺序:

1
ActiveRecord::Base.connection.reset_pk_sequence!('table_name')

现在ActiveRecord应该具有正确的序列值,并且应该能够正确地分配新的id。

解决错误

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint"moderations_reportable" DETAIL: Key (reportable_type, reportable_id)=(Post, 25) already exists. : INSERT INTO"moderations" ("blog_id","reportable_type","reportable_id","created_at","updated_at","blog_type") VALUES ($1, $2, $3, $4, $5, $6) RETURNING"id"

"调节"表上发生错误。

从rails console fix运行以下命令

1
ActiveRecord::Base.connection.reset_pk_sequence!('moderations')

谢谢


修复所有数据库的pkey序列:

1
2
3
ActiveRecord::Base.connection.tables.each do |table_name|
  ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
end


看起来您已为数据库添加了唯一索引:

1
t.index ["reportable_type","reportable_id"], name:"moderations_reportable", unique: true

使用唯一索引,您只能拥有一条具有相同reportable_typereportable_id的记录。 您可能正在尝试为已经具有审核功能的报告创建审核。