Mi Script framework to rearrange topics and categories ha crecido una nueva función que va un poco más allá de reorganizar temas y categorías.
Normalmente recuerdo advertir que no sé ruby ni ruby on rails, así que mi código es idiosincrásico en lugar de idiomático. ¡Pero parece que funciona hasta ahora en mis pruebas!
def migrateRetortToReactions(allowed:, likes: nil, emojimap: nil)
# migrar siempre que sea posible sin anular los likes existentes
# esta es una conversión necesariamente con pérdida de datos, y es consistente solo por el orden de PostDetail
# no se intenta preferir un registro de PostDetail sobre otro
emojimap = {} if emojimap.nil?
allowed.each do |a|
emojimap[a] = a
end
retort = "retort".freeze
emojiType = "emoji".freeze
usermap = Hash.new { |hash, username| hash[username] = User.find_by_username(username) }
postmap = Hash.new { |hash, post_id| hash[post_id] = Post.find(post_id) }
likeType = PostActionType.where(name_key: "like").pluck(:id).first
PostDetail.where(extra: retort).each do |pd|
begin
p = postmap[pd.post_id]
rescue
# PostDetail no es consistente con respecto a la eliminación
$stderr.puts sprintf("No se pudo encontrar la publicación para %d: %s / %s", pd.post_id, pd.key, pd.value)
next
end
emoji = pd.key.split('|').first
users = JSON.parse(pd.value)
users.each do |user|
u = usermap[user]
next if u.nil? # el nombre de usuario cambiado o el usuario eliminado dejan Retorts huérfanos
if likes.include?(emoji)
pa = PostAction.where(post_id: p.id, user_id: u.id, post_action_type_id: likeType).first
next unless pa.nil?
$stderr.puts sprintf("Añadiendo like para Retort %s para el usuario %s en %s", emoji, user, p.url)
PostActionCreator.create(u, p, :like, created_at: pd.created_at, silent: true)
elsif emojimap.has_key?(emoji)
e = emojimap[emoji]
r = DiscourseReactions::Reaction.where(post_id: p.id, reaction_type: emojiType, reaction_value: e).first_or_create
ru = DiscourseReactions::ReactionUser.where(user_id: u.id, post_id: p.id).first
next unless ru.nil?
$stderr.puts sprintf("Convirtiendo Retort %s a Reaction %s para el usuario %s en %s", emoji, e, user, p.url)
DiscourseReactions::ReactionUser.create(reaction_id: r.id, user_id: u.id, post_id: p.id, created_at: pd.created_at)
else
$stderr.puts sprintf("Ignorando Retort no mapeado %s para el usuario %s en %s", emoji, user, p.url)
end
end
end
end
Uso el framework que construí para proporcionar una configuración yaml que se ve así:
- migrateRetortToReactions:
allowed:
- rofl
- astonished
- crossed_fingers
- sob
- thinking
- grimacing
- frowning_face
- drum
likes:
- dart
- +1
- joy
- "100"
- brain
- heart
- heart_eyes
- hearts
emojimap:
rage: sob
four_leaf_clover: crossed_fingers
cry: sob
open_mouth: astonished
scream: frowning_face
Sin embargo, podrías simplemente envolver eso en un script de ruby, incluyendo hacer que esos argumentos sean código ruby literal, colocarlo en el directorio script/ y ejecutarlo.