PostRevisor no puede editar publicaciones en temas eliminados

Resumen

Para algunas publicaciones, llamar a PostRevisor establece post_id en nil. ¿Estoy loco?
Respuesta: No. PostRevisor accede a post.topic, que es nil para una publicación en un tema eliminado. Y luego establece post.topic en nil, lo que a su vez establece post.topic_id en nil.
Creo que PostRevisor debería obtener el tema así:

  @topic = topic || Topic.with_deleted.find_by(id: post_topic_id)

en lugar de así:

  @topic = topic
post=Post.find_by(topic_id: 179227, post_number: 12)
post.topic_id => 179227
pr=PostRevisor.new(post)
post.topic_id => nil

La historia completa

Estoy trabajando en un script que corrige enlaces goo.gl (el servicio está desapareciendo pronto, por lo que el script encuentra enlaces goo.gl, obtiene a qué se redirigen y reemplaza la URL goo.gl con la que se redirige. En su mayor parte funciona.

Pero

Para muchas publicaciones, todo parece ir bien, pero luego PostRevisor falla porque post.acting_user es nil. Y luego, en mi rescate, parece que topic_id es nil, pero no es el post el que es nil, porque todavía tiene un post_number.

      begin
        puts "Revisando (#{count}/#{total_posts}) https://mysite.com/t/#{post.topic_id}/#{post.post_number}"
        puts "topic_id faltante para la publicación #{post.id}" if !post.topic_id
        next if !post.topic_id
        PostRevisor.new(post).revise!(system_user, raw: new_raw, **revision_options)
      rescue => e
        puts "no se puede revisar (número: #{count} https://tw.forumosa.com/t/#{post.topic_id}/#{post.post_number}): #{e}"
      end
¡¡CORRIGIENDO!!: https://goo.gl/maps/XaNG
B7qaZGzhBmM78 -----> https://www.google.com/maps/place/%E6%AD%A5%E9%81%93%E5%92%96%E5%95%A1%E9%A4%A8Cafe+Strada/@22.6300414,120.3153591,17z/data=!3m1!4b1!4m5!3m4!1s0x346e04944a9b3471:0x520c1f01c3d62e57!8m2!3d22.6301115!4d120.3175543?shorturl=1
Revisando (680/1773) https://mysite.com/t/207069/1817
no se puede revisar (número: 680 https://mysite.com/t//1817): método no definido `acting_user=' para nil

Para la gran mayoría de las publicaciones, esto funciona bien, pero para un subconjunto de ellas, falla de esta manera. Y si ejecuto el código manualmente línea por línea, obtengo lo mismo. Sin embargo, está empezando a parecer que, si hago un pr=PostRevisor.new(post), veo que la publicación en el registro pr no tiene topic_id y luego, si inspecciono la post, ahora tiene topic_id establecido en nil.

1 me gusta

Por cierto, ¿hay alguna razón por la que no estés editando directamente el modelo Post?

Porque si estás cambiando 3000 posts con gsub y una expresión regular complicada con un montón de casos límite (corrección: goo.gl, http://goo.gl, https://goo.gl, pero no toques https://maps.app.goo.gl, o https://map.goo.gl, y tal vez te limiten la velocidad de goo.gl, y así sucesivamente) ¡es posible que quieras recuperar el post antes de haberlo arruinado por completo!

¡Ha sido muy bueno poder ver las ediciones y ver el antes y el después y poder revertir! Una versión convertiría https://maps.app.goo.gl/abd12 en algo como https://maps.app.https://maps.google.com/;lkajw3rpoazse;flknmase;faijserfasefklasdfa, por ejemplo.

1 me gusta

eso tiene sentido :slight_smile:

1 me gusta

Hace algunos años hubo un script similar que intenté que CDCK ejecutara para algún cliente y dijeron (en mis palabras, no en las suyas) “Tío. ¿Crees que vamos a ejecutar tu código que cambia a lo loco un montón de publicaciones y no hay forma de deshacerlo? Piénsalo de nuevo”.

1 me gusta

Sí, otro enfoque es ejecutarlo en una copia de seguridad en un área controlada. Pero me encanta tu solución.

1 me gusta

Aquí está el inicializador:

Entonces, de alguna manera la publicación llega allí y, aunque post_id tiene un valor, post no lo tiene.

Esto no lo puedo reproducir.
El último post.topic_id no es nil y, como se esperaba, es una repetición del resultado anterior.

Sí. Funcionó en la mayoría de las publicaciones. Hay algo raro con algunas de ellas.

[63] pry(main)> post.topic_id
=> 179227
[64] pry(main)> post.topic
=> nil
[65] pry(main)>

Estoy bastante seguro de que eso no debería suceder. :person_shrugging:

Pero espera:

Topic.find(post.topic_id)
ActiveRecord::RecordNotFound: No se pudo encontrar Topic con 'id'=179227 [WHERE "topics"."deleted_at" IS NULL]
from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/relation/finder_methods.rb:428:in `raise_record_not_found_exception!'

El tema está eliminado.

Entonces, la pregunta es si es un error que no se puedan revisar las publicaciones en temas eliminados.

Supongo que no me importará y haré que mi script verifique post.topic como nil en lugar de post.topic_id.

1 me gusta

¡Sí, hay una falta de integridad bastante desagradable ahí con la clave externa!

Creo que algunas de las barreras (ejem) están desactivadas porque las tablas suelen ser demasiado grandes.

Quizás alguien realizó un topic.delete en lugar de destroy. Ups.

Mi búsqueda de las publicaciones fue como Post.where("raw like '%goo.gl%'"), y eso devolverá publicaciones en temas eliminados. Y luego esas publicaciones tienen un topic_id, pero no un topic. Creo que hay alguna manera de hacer que Topic.find devuelva temas eliminados (porque un administrador puede ver esos temas, por eso estaba tan confundido. Esa pequeña papelera es fácil de pasar por alto).

Así que es así:

deleted_topic = Topic.with_deleted.find_by(id: 123)

¿Quizás debería haber hecho eso y actualizado la publicación antes de llamar a PostRevisor?

Pero en la UX puedo actualizar una publicación en un tema eliminado, así que estoy pensando que

def initialize(post, topic = post.topic)
  @post = post
  @topic = topic
  # Asegúrate de que solo tenemos una instancia de Topic
  post.topic = topic
end

debería ser

def initialize(post, topic = post.topic)
  @post = post
  @topic = topic || Topic.with_deleted.find_by(id: post_topic_id)
  # Asegúrate de que solo tenemos una instancia de Topic
  post.topic = topic
end

Voy a mover esto a Bug en caso de que alguien más piense que esto es uno.

Pero esto funciona:

        if !post.topic # las publicaciones en temas eliminados no tienen tema y rompen PostRevisor
           post.topic = Topic.with_deleted.find_by(id: post.topic_id)
           next if !post.topic
        end
        PostRevisor.new(post).revise!(system_user, raw: new_raw, **revision_options)

Había publicaciones en 3 temas que hicieron que Rails fallara. Me rindo con eso. :slight_smile:

1 me gusta

Y otra versión de lo anterior que hace un deleted_topic = Topic.with_deleted.find_by(id: 123) para actualizar post.topic también funciona.

Aun así, parece un error. O tal vez, dado que core hace algo más para gestionar esto, no es un error.

1 me gusta

¿O una característica faltante (y por lo tanto especificación)?

En línea, esto nunca se llamará para Publicaciones en Temas eliminados?

Sin embargo, estoy de acuerdo en que debería gestionarlo adecuadamente :thinking:

Quizás

Claramente están haciendo algo para permitir que funcione en publicaciones en temas eliminados, probablemente como yo.

Sí. Alguien que tome tales decisiones puede mover esto de regreso a Dev si lo considera apropiado.

Este tema se cerró automáticamente 30 días después de la última respuesta. Ya no se permiten nuevas respuestas.