This commit is contained in:
@@ -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
|
||||
|
||||
Generated
+25
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2026_03_29_034700) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2026_04_09_123700) do
|
||||
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "record_type", null: false
|
||||
@@ -132,6 +132,27 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_29_034700) do
|
||||
t.index ["tag_id"], name: "index_post_tags_on_tag_id"
|
||||
end
|
||||
|
||||
create_table "post_versions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "post_id", null: false
|
||||
t.integer "version_no", null: false
|
||||
t.string "event_type", null: false
|
||||
t.string "title"
|
||||
t.string "url", limit: 768, null: false
|
||||
t.string "thumbnail_base", limit: 2000
|
||||
t.text "tags", null: false
|
||||
t.bigint "parent_id"
|
||||
t.datetime "original_created_from"
|
||||
t.datetime "original_created_before"
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "created_by_user_id"
|
||||
t.index ["created_by_user_id"], name: "index_post_versions_on_created_by_user_id"
|
||||
t.index ["parent_id"], name: "index_post_versions_on_parent_id"
|
||||
t.index ["post_id", "version_no"], name: "index_post_versions_on_post_id_and_version_no", unique: true
|
||||
t.index ["post_id"], name: "index_post_versions_on_post_id"
|
||||
t.check_constraint "`event_type` in (_utf8mb4'create',_utf8mb4'update',_utf8mb4'discard',_utf8mb4'restore')"
|
||||
t.check_constraint "`version_no` > 0"
|
||||
end
|
||||
|
||||
create_table "posts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "title"
|
||||
t.string "url", limit: 768, null: false
|
||||
@@ -362,6 +383,9 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_29_034700) do
|
||||
add_foreign_key "post_tags", "tags"
|
||||
add_foreign_key "post_tags", "users", column: "created_user_id"
|
||||
add_foreign_key "post_tags", "users", column: "deleted_user_id"
|
||||
add_foreign_key "post_versions", "posts"
|
||||
add_foreign_key "post_versions", "posts", column: "parent_id"
|
||||
add_foreign_key "post_versions", "users", column: "created_by_user_id"
|
||||
add_foreign_key "posts", "posts", column: "parent_id"
|
||||
add_foreign_key "posts", "users", column: "uploaded_user_id"
|
||||
add_foreign_key "settings", "users"
|
||||
|
||||
Reference in New Issue
Block a user