J'ai un modèle Post
et chaque fois qu'une publication est créée, je veux qu'une nouvelle instance de Moderation
soit créée en même temps.
Donc, dans post.rb, j'utilise le rappel after_save :create_moderation
Puis écrivez une méthode privée:
...
include Reportable
after_save :create_moderation
private
def create_moderation
self.create_moderation!(blog: Blog.first)
end
Mais lorsqu'une proposition est créée, j'obtiens cette erreur:
PG :: UniqueViolation: ERREUR: la valeur de clé en double viole la contrainte unique "moderations_reportable" DÉTAIL: La clé (reportable_type, reportable_id) = (Post, 25) existe déjà. : INSERT INTO "moderations" ("blog_id", "reportable_type", "reportable_id", "created_at", "updated_at", "blog_type") VALUES ($ 1, $ 2, $ 3, $ 4, $ 5, $ 6) RETURNING "id"
Dans reportable.rb j'ai:
has_one :moderation, as: :reportable, foreign_key: "reportable_id", foreign_type: "reportable_type", class_name: "Moderation"
Puis quelques autres méthodes pour l'objet à signaler.
Notez que ce problème ne se produit pas lorsque j'exécute la méthode create dans la console.
MODIFIER
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
Il semble que vous ayez ajouté un index unique à votre base de données:
t.index ["reportable_type", "reportable_id"], name: "moderations_reportable", unique: true
Avec un index unique, vous ne pourrez avoir qu'un seul enregistrement avec le même reportable_type
et reportable_id
. Il est probable que vous essayiez de créer une modération pour un rapportable qui a déjà une modération.
Pour résoudre le problème, nous devons dire à ActiveRecord de regarder la séquence de la table:
ActiveRecord::Base.connection.reset_pk_sequence!('table_name')
Maintenant, ActiveRecord devrait avoir la valeur de séquence correcte et devrait être en mesure d'attribuer correctement les nouveaux identifiants.
Pour résoudre l'erreur
PG :: UniqueViolation: ERREUR: la valeur de clé en double viole la contrainte unique "moderations_reportable" DÉTAIL: La clé (reportable_type, reportable_id) = (Post, 25) existe déjà. : INSERT INTO "moderations" ("blog_id", "reportable_type", "reportable_id", "created_at", "updated_at", "blog_type") VALUES ($ 1, $ 2, $ 3, $ 4, $ 5, $ 6) RETURNING "id"
Comme une erreur s'est produite sur la table des "modérations".
Exécutez ce qui suit depuis console Rails correction
ActiveRecord::Base.connection.reset_pk_sequence!('moderations')
Je vous remercie
Correction des séquences pkey pour toutes les bases de données:
ActiveRecord::Base.connection.tables.each do |table_name|
ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
end