Intento de recrear canal de chat eliminado con el mismo nombre (todavía) falla

Continuando la discusión de El intento de recrear un canal de chat eliminado con el mismo nombre falla:

Este error se informó en el hilo vinculado, pero parece que todavía persiste para mí. Estoy en la última versión, hice un git pull y reconstruí el lanzador ayer.

Al intentar nombrar un nuevo canal de chat con el nombre de cualquier canal de chat utilizado anteriormente, hay un error 500 en la consola de JavaScript.

En los registros de errores de Discourse, obtengo:

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.

En la consola de Rails, puedo ver que los ChatChannels eliminados se han ido, pero sospecho que en algún lugar el slug eliminado permanece en un índice o en alguna otra dependencia de la base de datos y no se ha eliminado.

Esta solución alternativa no funciona para mí; al intentar renombrar “foo2” a “foo”, obtengo el mismo error 500, debido a la restricción de unicidad fallida en el slug.

No estoy seguro de cómo eliminar de forma segura los slugs (¿indexados?) de los ChatChannels eliminados, pero estaría dispuesto a intentarlo.


Posiblemente relacionado: este problema que también afecta a los slugs, pero no parece ser el mismo problema: Attempt to recreate deleted chat channel with same name fails

2 Me gusta

Acabo de probar lo siguiente y no tuve ningún problema:

  1. Crear canal con nombre “whiskers” y slug “whiskers”
  2. Eliminar canal
  3. Crear canal con nombre “whiskers” y slug “whiskers”

Eso funcionó.

Cuando se elimina el canal (paso 2), el slug se cambia automáticamente a algo único. Pero como eliminaste tu canal antes de que se introdujera ese cambio, es posible que el slug antiguo todavía esté presente.

Probablemente puedas actualizar manualmente el slug del canal eliminado a través de la consola de Rails, pero no estoy seguro de cuál es la sintaxis correcta. Preguntaré.

Tenga en cuenta también que ahora los slugs de los canales se pueden editar independientemente del nombre del canal, por lo que, como solución alternativa, también podría crear un canal con el nombre deseado hoy y elegir un slug diferente que no entre en conflicto.

2 Me gusta

Esto es súper inesperado.

No eliminamos canales, solo los eliminamos de forma lógica. Por lo tanto, todavía deberían estar aquí con la columna deleted_at rellena.

Si ejecutas esto en tu consola, ¿no obtienes resultados?

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

Confirmo que esta prueba también funciona para mí en mi instancia, que está completamente actualizada.

Creo que el problema es que en algún lugar de la base de datos hay algún slug pendiente que debería haber sido eliminado, pero no lo fue, tal vez hubo un error en una versión anterior que ahora está corregido. El chat solo se ha habilitado en esta instancia durante 17 días, por lo que cualquier error tendría que haber estado activo en ese período de tiempo.

1 me gusta

No puedo reproducir esto de ninguna manera. Después de hacer una copia de seguridad de la base de datos, quizás puedas probar esto en la consola de Rails. Parece sorprendente, sin embargo.

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

He comprobado y esto es lo esperado, ya que excluimos los registros con deleted_at relleno incluso 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

Necesitarás hacer esto en su lugar (añadiendo 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>

Así que para limpiar el antiguo slug del canal eliminado haz algo como esto:

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

¿Quizás necesitamos una migración para arreglar esto @mcwumbly y @j.jaffeux?

2 Me gusta

Oh sí, claro, olvidé el with_deleted en este caso :+1:

Sugiero que dejemos tu respuesta aquí por ahora. Debería ser un caso raro: eliminado antes de la corrección + quiere recrear con el mismo nombre.

4 Me gusta

Gracias por lo anterior. No sabía sobre with_deleted, pero eso me permitió ver las instancias eliminadas y renombrar sus slugs según tu fragmento.

Confirmo que esto está solucionado. Estaría de acuerdo con @j.jaffeux en que es poco probable que esto afecte a muchos usuarios, así que diría que es suficiente que haya una solución de consola de Rails en el hilo.

3 Me gusta

Excelente, me alegra saber que lo resolvió por usted, Marcus. Cierro este tema ahora.

2 Me gusta

Cuando intento crear un nuevo canal (llamado “general”, igual para el slug) aparece el siguiente error en los logs (no pasa nada en el frontend).

No se muestran canales “Cerrados”.

Es posible que haya tenido un canal general en el pasado y probablemente lo haya eliminado (¿es predeterminado?).

No puedo reproducirlo con otro slug aleatorio (crear > eliminar > crear funciona perfectamente).

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.

He trasladado tu publicación aquí para mantener los informes agrupados. :+1:

¿Sería la solución provisional anterior adecuada en tu caso también?

La solución alternativa en OP, no, no funcionó.

Esto tampoco pareció funcionar para mí.

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

La solución alternativa para el problema de los OP está en esta publicación:

2 Me gusta

Probé esto, de eso se trataba mi bloque de código compartido.

No pude ejecutar estos comandos en rails.

¿Quizás estoy haciendo algo mal aquí?

EDITAR: para ser claro, la solución alternativa sugerida genera el mismo error al buscar el canal

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

De acuerdo, logré resolver el problema (al menos, creo que sí).

Para mí fue un poco complicado descifrar todo esto, así que compartiré los pasos completos.

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

Así que en tu consola de rails esto se verá así:

[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) ✗

Ahora puedo crear un nuevo canal con el slug deseado.

¿Es esta la forma correcta (o una de ellas)?

2 Me gusta

La solución provisional que falla anteriormente se debe a un espacio de nombres que introdujimos hace semanas. ChatChannel ahora es Chat::Channel.

1 me gusta

Esperaba algo así pero no pude encontrarlo. ¿Espero que mi cambio de BD sea también una buena solución provisional? Hasta ahora no hay problemas.

2 Me gusta