tl;dr
Для некоторых постов вызов PostRevisor устанавливает post_id в nil. Я что, с ума схожу?
Ответ: Нет. PostRevisor обращается к post.topic, который равен nil для поста в удалённой теме. Затем он устанавливает post.topic в nil, что, в свою очередь, обнуляет post.topic_id.
Я считаю, что PostRevisor должен получать тему следующим образом:
@topic = topic || Topic.with_deleted.find_by(id: post_topic_id)
а не так:
@topic = topic
post=Post.find_by(topic_id: 179227, post_number: 12)
post.topic_id => 179227
pr=PostRevisor.new(post)
post.topic_id => nil
Полная история
Я работаю над скриптом, который исправляет ссылки goo.gl (сервис скоро прекратит работу, поэтому скрипт находит ссылки goo.gl, получает адрес, на который они перенаправляют, и заменяет ссылку goo.gl на конечный URL с помощью gsub. В основном всё работает.
Но
Для группы постов всё выглядит отлично, но затем PostRevisor падает, потому что post.acting_user равен nil. Затем в блоке rescue кажется, что topic_id равен nil, но сам post не равен nil, поскольку у него всё ещё есть post_number.
begin
puts "Revising (#{count}/#{total_posts}) https://mysite.com/t/#{post.topic_id}/#{post.post_number}"
puts "missing topic_id for post #{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 "cannot revise (number: #{count} https://tw.forumosa.com/t/#{post.topic_id}/#{post.post_number}): #{e}"
end
FIXING!!: 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/d
ata=!3m1!4b1!4m5!3m4!1s0x346e04944a9b3471:0x520c1f01c3d62e57!8m2!3d22.6301115!4d120.3175543?shorturl=1
Revising (680/1773) https://mysite.com/t/207069/1817
cannot revise (number: 680 https://mysite.com/t//1817): undefined method `acting_user=' for nil
Для подавляющего большинства постов всё работает отлично, но для некоторой их части происходит сбой именно таким образом. Если я запускаю код вручную, строка за строкой, результат тот же. Однако начинает казаться, что если выполнить pr=PostRevisor.new(post), то в объекте pr у поста будет отсутствовать topic_id, а при инспекции самого объекта post окажется, что его topic_id теперь установлен в nil.