This commit is contained in:
2026-04-09 23:33:18 +09:00
parent b2d72ffcb0
commit 625507abf6
4 changed files with 83 additions and 61 deletions
@@ -1,5 +1,17 @@
class CreatePostVersions < ActiveRecord::Migration[8.0]
def change
class Post < ApplicationRecord
self.table_name = 'posts'
end
class PostTag < ApplicationRecord
self.table_name = 'post_tags'
end
class PostVersion < ApplicationRecord
self.table_name = 'post_versions'
end
def up
create_table :post_versions do |t|
t.references :post, null: false, foreign_key: true
t.integer :version_no, null: false
@@ -19,62 +31,45 @@ class CreatePostVersions < ActiveRecord::Migration[8.0]
t.check_constraint "event_type IN ('create', 'update', 'discard', 'restore')"
end
reversible do |dir|
dir.up do
execute <<~SQL
INSERT INTO
post_versions(
post_id
, version_no
, event_type
, title
, url
, thumbnail_base
, tags
, parent_id
, original_created_from
, original_created_before
, created_at
, created_by_user_id)
SELECT
posts.id
, 1
, 'create'
, posts.title
, posts.url
, posts.thumbnail_base
, COALESCE(tag_snapshots.tags, '')
, posts.parent_id
, posts.original_created_from
, posts.original_created_before
, posts.created_at
, posts.uploaded_user_id
FROM
posts
LEFT JOIN
(
SELECT
post_tags.post_id
, GROUP_CONCAT(tag_names.name ORDER BY tag_names.name SEPARATOR ' ') AS tags
FROM
post_tags
INNER JOIN
tags
ON
tags.id = post_tags.tag_id
INNER JOIN
tag_names
ON
tag_names.id = tags.tag_name_id
WHERE
post_tags.discarded_at IS NULL
GROUP BY
post_tags.post_id
) tag_snapshots
ON
tag_snapshots.post_id = posts.id
SQL
say_with_time 'Backfilling post_versions' do
Post.find_in_batches(batch_size: 500) do |posts|
post_ids = posts.map(&:id)
tag_names_by_post_id =
PostTag
.joins('INNER JOIN tags ON tags.id = post_tags.tag_id')
.joins('INNER JOIN tag_names ON tag_names.id = tags.tag_name_id')
.where(post_id: post_ids)
.where('post_tags.discarded_at IS NULL')
.where('tags.discarded_at IS NULL')
.where('tag_names.discarded_at IS NULL')
.pluck('post_tags.post_id', 'tag_names.name')
.each_with_object(Hash.new { |h, k| h[k] = [] }) do |(post_id, tag_name), h|
h[post_id] << tag_name
end
rows = posts.map do |post|
tags = tag_names_by_post_id[post.id].uniq.sort.join(' ')
{ post_id: post.id,
version_no: 1,
event_type: 'create',
title: post.title,
url: post.url,
thumbnail_base: post.thumbnail_base,
tags:,
parent_id: post.parent_id,
original_created_from: post.original_created_from,
original_created_before: post.original_created_before,
created_at: post.created_at,
created_by_user_id: post.uploaded_user_id }
end
PostVersion.insert_all!(rows) if rows.present?
end
end
end
def down
drop_table :post_versions
end
end