Tentativo di ricreare il canale di chat eliminato con lo stesso nome (ancora) fallisce

Continuando la discussione da Tentativo di ricreare un canale di chat eliminato con lo stesso nome fallisce:

Questo bug è stato segnalato nel thread collegato ma sembra persistere per me. Sono sull’ultima versione e ho eseguito un git pull e una ricostruzione del launcher ieri.

Quando si tenta di nominare un nuovo canale di chat con un nome di canale di chat precedentemente utilizzato, si verifica un errore 500 nella console JS.

Nei log degli errori di Discourse ottengo

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.

Nella console Rails posso vedere che i ChatChannels eliminati non ci sono più, ma sospetto che da qualche parte la slug eliminata rimanga in un indice o in qualche altra dipendenza del database e non sia stata eliminata.

Questa soluzione alternativa non funziona per me, al tentativo di rinominare “foo2” in “foo” ottengo lo stesso errore 500, a causa del vincolo di unicità fallito sulla slug.

Non sono sicuro di come eliminare in modo sicuro le slug (indicizzate?) dei ChatChannels eliminati, ma sarei disposto a provarci.


Possibilmente correlato: questo problema che influisce anche sulle slug, ma non sembra essere lo stesso problema: Attempt to recreate deleted chat channel with same name fails

2 Mi Piace

Ho appena testato quanto segue e non ho riscontrato problemi:

  1. Crea canale con nome “whiskers” e slug “whiskers”
  2. Elimina canale
  3. Crea canale con nome “whiskers” e slug “whiskers”

Ha funzionato.

Quando il canale viene eliminato (passaggio 2), lo slug viene automaticamente modificato in qualcosa di univoco. Ma poiché hai eliminato il tuo canale prima che questa modifica venisse introdotta, lo slug precedente potrebbe essere ancora in giro.

Probabilmente puoi aggiornare manualmente lo slug per il canale eliminato tramite la console rails, ma non sono sicuro di quale sia la sintassi corretta. Chiederò in giro.

Nota anche che gli slug dei canali ora possono essere modificati indipendentemente dal nome del canale, quindi come soluzione alternativa, potresti anche creare oggi un canale con il nome desiderato e scegliere uno slug diverso che non sia in conflitto.

2 Mi Piace

Questo è super inaspettato.

Non eliminiamo i canali, li eliminiamo solo in modo “soft”. Quindi dovrebbero essere ancora qui con la colonna deleted_at compilata.

Se esegui questo nella tua console, non ottieni risultati?

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

Confermo che anche questo test funziona per me sulla mia istanza, che è completamente aggiornata.

Penso che il problema sia che da qualche parte nel DB ci sia uno slug in sospeso che avrebbe dovuto essere eliminato, ma non lo è stato, forse c’era un bug in una versione precedente che ora è stato corretto. La chat è stata abilitata su questa istanza solo 17 giorni fa, quindi qualsiasi bug avrebbe dovuto essere attivo in questo lasso di tempo.

1 Mi Piace

Non riesco a riprodurlo in alcun modo. Dopo aver eseguito un backup del database, potresti provare questi nella console di Rails. Sembra sorprendente, però.

[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);")

Ho controllato e questo è effettivamente previsto, poiché escludiamo i record con deleted_at compilato anche con find_by:

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

Dovrai fare questo invece (aggiungendo with_deleted):

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>

Quindi, per eliminare il vecchio slug del canale eliminato, fai qualcosa del genere:

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

Forse abbiamo bisogno di una migrazione per correggere questi @mcwumbly e @j.jaffeux?

2 Mi Piace

Oh sì, giusto, ho dimenticato with_deleted in questo caso :+1:

Suggerisco di lasciare la tua risposta qui per ora. Dovrebbe essere un caso raro: eliminato prima della correzione + vuole ricreare con lo stesso nome.

4 Mi Piace

Grazie per quanto sopra. Non ero a conoscenza di with_deleted ma ciò mi ha permesso di vedere le istanze eliminate e rinominare i loro slug come da tuo snippet.

Confermo che questo è stato risolto. Concorderei con @j.jaffeux sul fatto che è improbabile che ciò influenzi molti utenti, quindi direi che è sufficiente che una correzione nella console Rails sia qui nel thread.

3 Mi Piace

Ottimo, sono contento che abbia risolto il problema per te Marcus. Chiudo questo argomento ora.

2 Mi Piace

Quando tento creare un nuovo canale (chiamato “general”, stesso per lo slug) viene visualizzato il seguente errore nei log (non succede nulla sul frontend).

Non vengono mostrati canali “Chiusi”.

Potrei aver avuto un canale general in passato - e probabilmente l’ho cancellato (è predefinito?)

Non riesco a riprodurlo con un altro slug casuale (crea > cancella > crea funziona perfettamente).

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.

Ho spostato il tuo post qui per mantenere i report raggruppati. :+1:

La soluzione temporanea sopra sarebbe adatta anche nel tuo caso?

La soluzione temporanea in OP, no, non ha funzionato.

Anche questo non sembra aver funzionato per me.

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

La soluzione alternativa per il problema dell’OP si trova in questo post:

2 Mi Piace

Ho provato questi, è di questo che parlava il mio blocco di codice condiviso.

Non sono riuscito a eseguire questi comandi in rails.

Forse sto facendo qualcosa di sbagliato qui?

EDIT: per essere chiari, la soluzione alternativa suggerita genera lo stesso errore quando si cerca il canale

[7] pry(main)> ChatChannel.with_deleted.find_by(slug: "general")
NameError: uninitialized constant ChatChannel
from (pry):7:in `__pry__'
2 Mi Piace

Va bene, sono riuscito a risolvere il problema (almeno, credo).\n\nPer me è stato un po’ complicato capire tutto questo, quindi condividerò i passaggi completi.\n\njs\ncd /var/discourse &amp;&amp; ./launcher enter app\nrails c\nDB.exec(\"UPDATE chat_channels SET slug = 'new' WHERE slug = 'old';\")\n\nQuindi, nella tua console rails, apparirà così:\n\njs\n[1] pry(main)> DB.exec(\"UPDATE chat_channels SET slug = 'new' WHERE slug = 'old';\")\n=&gt; 1\n[2] pry(main)> exit\nroot@discourse-app:~# exit\nlogout\n➜ discourse git:(main) ✗ \n\nOra sono in grado di creare un nuovo canale con lo slug desiderato.\n\nQuesto è il modo giusto (o uno dei modi giusti)?

2 Mi Piace

La soluzione temporanea che non funziona sopra è dovuta a una qualche introduzione di namespace che abbiamo fatto settimane fa. ChatChannel ora è Chat::Channel

1 Mi Piace

Mi aspettavo qualcosa del genere ma non sono riuscito a trovarlo. Spero che anche la mia modifica al DB sia una buona soluzione alternativa? Finora nessun problema.

2 Mi Piace