Versuch, gelöschten Chat-Kanal mit demselben Namen wiederherzustellen (immer noch) schlägt fehl

Fortsetzung der Diskussion aus Attempt to recreate deleted chat channel with same name fails:

Dieser Fehler wurde im verlinkten Thread gemeldet, scheint aber bei mir immer noch zu bestehen. Ich bin auf der neuesten Version, habe gestern git pull ausgeführt und den Launcher neu erstellt.

Beim Versuch, einen neuen Chat-Kanal nach einem zuvor verwendeten Chat-Kanalnamen zu benennen, tritt ein 500-Fehler in der JS-Konsole auf.

In den Discourse-Fehlerprotokollen erhalte ich:

Failed to handle exception in exception app middleware : ActiveRecord::RecordNotUnique : PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_chat_channels_on_slug"
DETAIL:  Key (slug)=(sec-fhir) already exists.

In der Rails-Konsole kann ich sehen, dass die gelöschten ChatChannels verschwunden sind, aber ich vermute, dass der gelöschte Slug irgendwo in einem Index oder einer anderen Datenbankabhängigkeit verbleibt und nicht gelöscht wurde.

Dieser Workaround funktioniert bei mir nicht. Beim Versuch, „foo2“ in „foo“ umzubenennen, erhalte ich denselben 500-Fehler, da die Eindeutigkeitsbeschränkung für den Slug fehlgeschlagen ist.

Ich bin mir nicht sicher, wie ich die (indizierten?) Slugs von gelöschten ChatChannels sicher löschen kann, aber ich wäre bereit, es zu versuchen.


Möglicherweise zusammenhängend: Dieses Problem, das sich ebenfalls auf Slugs auswirkt, scheint jedoch nicht dasselbe Problem zu sein: Attempt to recreate deleted chat channel with same name fails

2 „Gefällt mir“

Ich habe gerade Folgendes getestet und hatte keine Probleme:

  1. Kanal mit dem Namen „whiskers“ und dem Slug „whiskers“ erstellen
  2. Kanal löschen
  3. Kanal mit dem Namen „whiskers“ und dem Slug „whiskers“ erstellen

Das hat funktioniert.

Wenn der Kanal gelöscht wird (Schritt 2), wird der Slug automatisch in etwas Einzigartiges geändert. Da Sie Ihren Kanal jedoch vor der Einführung dieser Änderung gelöscht haben, ist der alte Slug möglicherweise noch vorhanden.

Sie können den Slug für den gelöschten Kanal wahrscheinlich manuell über die Rails-Konsole aktualisieren, aber ich bin mir nicht sicher, wie der richtige Befehl lautet. Ich werde mich umhören.

Beachten Sie auch, dass Kanal-Slugs jetzt unabhängig vom Kanalnamen bearbeitet werden können. Als Workaround könnten Sie heute auch einen Kanal mit dem gewünschten Namen erstellen und einen anderen Slug wählen, der nicht in Konflikt steht.

2 „Gefällt mir“

Das ist unerwartet.

Wir löschen Kanäle nicht, wir löschen sie nur soft. Sie sollten also noch hier sein, mit der deleted_at-Spalte gefüllt.

Wenn Sie dies in Ihrer Konsole ausführen, erhalten Sie keine Ergebnisse?

ChatChannel.find_by(slug: "sec-fhir")
[1] pry(main)> ChatChannel.find_by(slug: "sec-fhir")
=> nil

Ich kann bestätigen, dass dieser Test auch auf meiner Instanz funktioniert, die auf dem neuesten Stand ist.

Ich denke, das Problem ist, dass irgendwo in der Datenbank ein Slug herumhängt, der hätte gelöscht werden sollen, aber nicht wurde. Möglicherweise gab es in einer früheren Version einen Fehler, der jetzt behoben ist. Chat ist auf dieser Instanz erst seit 17 Tagen aktiviert, daher müsste ein Fehler innerhalb dieses Zeitrahmens aktiv gewesen sein.

1 „Gefällt mir“

Kann dies in keiner Weise reproduzieren. Nachdem Sie ein DB-Backup durchgeführt haben, können Sie diese im Rails-Konsolenversuch ausführen. Scheint aber überraschend.

[1] pry(main)> DB.exec("DROP INDEX IF EXISTS index_chat_channels_on_slug;")
[2] pry(main)> DB.exec("CREATE UNIQUE INDEX index_chat_channels_on_slug ON chat_channels(slug);")

Ich habe nachgesehen und das ist tatsächlich zu erwarten, da wir Datensätze mit einem ausgefüllten deleted_at-Wert auch bei find_by ausschließen:

ChatChannel.find_by(slug: "sec-fhir")
  ChatChannel Load (0.4ms)  SELECT "chat_channels".* FROM "chat_channels" WHERE "chat_channels"."deleted_at" IS NULL AND "chat_channels"."slug" = 'sec-fhir' LIMIT 1
=> nil

Sie müssen stattdessen Folgendes tun (fügen Sie with_deleted hinzu):

ChatChannel.with_deleted.find_by(slug: "sec-fhir")
  ChatChannel Load (0.3ms)  SELECT "chat_channels".* FROM "chat_channels" WHERE "chat_channels"."slug" = 'sec-fhir' LIMIT 1
=> #<CategoryChannel:0x00007fc9bfb4abf0
 id: 124,
 chatable_id: 19,
 deleted_at: Wed, 15 Feb 2023 01:19:20.982181000 UTC +00:00,
 deleted_by_id: nil,
 featured_in_category_id: nil,
 delete_after_seconds: nil,
 chatable_type: "Category",
 created_at: Fri, 13 Jan 2023 01:46:43.730329000 UTC +00:00,
 updated_at: Wed, 15 Feb 2023 01:19:56.427647000 UTC +00:00,
 name: "test channel",
 description: "",
 status: "archived",
 user_count: 1,
 last_message_sent_at: Fri, 13 Jan 2023 01:46:51.130903000 UTC +00:00,
 auto_join_users: false,
 user_count_stale: false,
 slug: "sec-fhir",
 type: "CategoryChannel",
 allow_channel_wide_mentions: true,
 messages_count: 0,
 threading_enabled: false>

Um den alten gelöschten Kanal-Slug zu bereinigen, tun Sie also etwas wie das hier:

channel = ChatChannel.with_deleted.find_by(slug: "sec-fhir")
channel.update!(slug: "#{channel.deleted_at.strftime("%Y%m%d-%H%M")}-#{channel.slug}-deleted")

Vielleicht brauchen wir eine Migration, um diese zu beheben, @mcwumbly und @j.jaffeux?

2 „Gefällt mir“

Ja, richtig, ich habe in diesem Fall with_deleted vergessen :+1:

Ich schlage vor, wir lassen deine Antwort hier vorerst stehen. Sollte ein seltener Fall sein: vor der Korrektur gelöscht + möchte mit demselben Namen neu erstellen.

4 „Gefällt mir“

Danke für das Obige. Ich wusste nichts von with_deleted, aber das ermöglichte mir, die gelöschten Instanzen zu sehen und ihre Slugs wie in Ihrem Snippet umzubenennen.

Ich kann bestätigen, dass dies behoben ist. Ich stimme @j.jaffeux zu, dass dies wahrscheinlich nicht viele Benutzer betrifft, daher würde ich sagen, dass eine Korrektur in der Rails-Konsole hier im Thread ausreichend ist.

3 „Gefällt mir“

Ausgezeichnet, gut zu hören, dass es für Sie Marcus gelöst wurde. Ich schließe dieses Thema nun.

2 „Gefällt mir“

Wenn ich versuche, einen neuen Kanal zu erstellen (benannt „general“, gleicher Slug), wird im Protokoll der folgende Fehler angezeigt (im Frontend passiert nichts).

Es werden keine „geschlossenen“ Kanäle angezeigt.

Ich hatte vielleicht in der Vergangenheit einen allgemeinen Kanal – und ihn wahrscheinlich gelöscht (ist er standardmäßig vorhanden?).

Kann nicht mit einem anderen zufälligen Slug reproduzieren (erstellen > löschen > erstellen funktioniert einwandfrei).

Failed to handle exception in exception app middleware : ActiveRecord::RecordNotUnique : PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_chat_channels_on_slug"
DETAIL:  Key (slug)=(general) already exists.

Ich habe deinen Beitrag hierher verschoben, damit die Berichte zusammengefasst bleiben. :+1:

Wäre die oben genannte Problemumgehung auch in deinem Fall geeignet?

Der Workaround in OP, nein, hat nicht funktioniert.

Das schien auch bei mir nicht zu funktionieren.

[1] pry(main)> ChatChannel.find_by(slug: "general")
NameError: uninitialized constant ChatChannel
from (pry):1:in `__pry__'

Der Workaround für das Problem des OP befindet sich in diesem Beitrag:

2 „Gefällt mir“

Ich habe diese ausprobiert, darum ging es in meinem geteilten Codeblock.

Ich habe diese Befehle nicht in Rails ausführen können.

Vielleicht mache ich hier etwas falsch?

EDIT: Um es klarzustellen, der vorgeschlagene Workaround führt beim Suchen des Kanals zum selben Fehler

[7] pry(main)> ChatChannel.with_deleted.find_by(slug: "general")
NameError: uninitialized constant ChatChannel
from (pry):7:in `__pry__'
2 „Gefällt mir“

Okay, ich habe das Problem gelöst (zumindest glaube ich das).

Für mich war es etwas mühsam, das alles herauszufinden, also werde ich die vollständigen Schritte teilen.

cd /var/discourse & ./launcher enter app
rails c
DB.exec("UPDATE chat_channels SET slug = 'new' WHERE slug = 'old';")

In Ihrer Rails-Konsole wird dies also so aussehen:

[1] pry(main)> DB.exec("UPDATE chat_channels SET slug = 'new' WHERE slug = 'old';")
=> 1
[2] pry(main)> exit
root@discourse-app:~# exit
logout
➜  discourse git:(main) ✗

Ich kann jetzt einen neuen Kanal mit dem gewünschten Slug erstellen.

Ist dies der (oder ein) richtige Weg?

2 „Gefällt mir“

Der oben genannte Workaround schlägt fehl, da wir vor Wochen eine Namensraumung eingeführt haben. ChatChannel ist jetzt Chat::Channel.

1 „Gefällt mir“

Ich habe so etwas erwartet, konnte es aber nicht finden. Ich hoffe, meine DB-Änderung ist auch eine gute Übergangslösung? Bisher keine Probleme.

2 „Gefällt mir“