我有一个模型Post
,每次创建帖子时,我都希望同时创建一个Moderation
的新实例。
所以在post.rb中我使用了回调after_save :create_moderation
然后写一个私有方法:
...
include Reportable
after_save :create_moderation
private
def create_moderation
self.create_moderation!(blog: Blog.first)
end
但是当创建提案时,我收到此错误:
PG :: UniqueViolation:错误:重复键值违反了唯一约束" moderations_reportable" DETAIL:Key(reportable_type,reportable_id)=(Post,25)已经存在。 :INSERT INTO"审核" (" blog_id"," reportable_type"," reportable_id"," created_at"," updated_at"," blog_type")价值($ 1,$ 2,$ 3,$ 4,$ 5,$ 6)返回" id"
在reportable.rb中我有:
has_one :moderation, as: :reportable, foreign_key: "reportable_id", foreign_type: "reportable_type", class_name: "Moderation"
然后很少有其他可报告对象的方法。
请注意,当我在控制台中运行create方法时,这个问题不会发生。
修改
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
答案 0 :(得分:18)
要解决此问题,我们必须告诉ActiveRecord查看表的序列:
ActiveRecord::Base.connection.reset_pk_sequence!('table_name')
现在ActiveRecord应该具有正确的序列值,并且应该能够正确分配新的id。
解决错误
PG :: UniqueViolation:错误:重复键值违反了唯一约束" moderations_reportable" DETAIL:Key(reportable_type,reportable_id)=(Post,25)已经存在。 :INSERT INTO"审核" (" blog_id"," reportable_type"," reportable_id"," created_at"," updated_at"," blog_type")价值($ 1,$ 2,$ 3,$ 4,$ 5,$ 6)返回" id"
由于'审核错误发生在'表
从 rails控制台修复
运行以下命令ActiveRecord::Base.connection.reset_pk_sequence!('moderations')
谢谢
答案 1 :(得分:4)
看起来您已为数据库添加了唯一索引:
t.index ["reportable_type", "reportable_id"], name: "moderations_reportable", unique: true
使用唯一索引,您只能拥有一条具有相同reportable_type
和reportable_id
的记录。您可能正在尝试为已经审核的报告创建审核。
答案 2 :(得分:4)
修复所有数据库的pkey序列:
ActiveRecord::Base.connection.tables.each do |table_name|
ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
end
答案 3 :(得分:1)
仅适用于在运行测试时看到此内容的人
一个可能的原因是,您有一些创建新数据记录的迁移,并且您最近运行了以下其中一项。
rake db:migrate RAILS_ENV=test
或
rake db:migrate:reset RAILS_ENV=test
您需要清理/清除您的测试数据库。运行这个
rake db:reset RAILS_ENV=test
这将从 schema.rb
清除并生成架构。