Browse Source

#264

pull/307/head
みてるぞ 5 days ago
parent
commit
625507abf6
4 changed files with 83 additions and 61 deletions
  1. +5
    -2
      backend/app/models/post_version.rb
  2. +2
    -2
      backend/app/services/post_version_recorder.rb
  3. +51
    -56
      backend/db/migrate/20260409123700_create_post_versions.rb
  4. +25
    -1
      backend/db/schema.rb

+ 5
- 2
backend/app/models/post_version.rb View File

@@ -11,9 +11,12 @@ class PostVersion < ApplicationRecord
belongs_to :parent, class_name: 'Post', optional: true belongs_to :parent, class_name: 'Post', optional: true
belongs_to :created_by_user, class_name: 'User', optional: true belongs_to :created_by_user, class_name: 'User', optional: true


enum :event_type, create: 'create', update: 'update', discard: 'discard', restore: 'restore'
enum :event_type, { create: 'create',
update: 'update',
discard: 'discard',
restore: 'restore' }, prefix: true, validate: true


validates :version_no, presence: true, numerically: { only_integer: true, greater_than: 0 }
validates :version_no, presence: true, numericality: { only_integer: true, greater_than: 0 }
validates :event_type, presence: true, inclusion: { in: event_types.keys } validates :event_type, presence: true, inclusion: { in: event_types.keys }
validates :url, presence: true validates :url, presence: true




+ 2
- 2
backend/app/services/post_version_recorder.rb View File

@@ -3,7 +3,7 @@ class PostVersionRecorder
new(post:, event_type:, created_by_user:).record! new(post:, event_type:, created_by_user:).record!
end end


def initialize post:, event_type:, created_user:
def initialize post:, event_type:, created_by_user:
@post = post @post = post
@event_type = event_type @event_type = event_type
@created_by_user = created_by_user @created_by_user = created_by_user
@@ -23,7 +23,7 @@ class PostVersionRecorder
title: attrs[:title], title: attrs[:title],
url: attrs[:url], url: attrs[:url],
thumbnail_base: attrs[:thumbnail_base], thumbnail_base: attrs[:thumbnail_base],
tags: attrs[:url],
tags: attrs[:tags],
parent: attrs[:parent], parent: attrs[:parent],
original_created_from: attrs[:original_created_from], original_created_from: attrs[:original_created_from],
original_created_before: attrs[:original_created_before], original_created_before: attrs[:original_created_before],


+ 51
- 56
backend/db/migrate/20260409123700_create_post_versions.rb View File

@@ -1,5 +1,17 @@
class CreatePostVersions < ActiveRecord::Migration[8.0] 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| create_table :post_versions do |t|
t.references :post, null: false, foreign_key: true t.references :post, null: false, foreign_key: true
t.integer :version_no, null: false 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')" t.check_constraint "event_type IN ('create', 'update', 'discard', 'restore')"
end 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 end
end end

def down
drop_table :post_versions
end
end end

+ 25
- 1
backend/db/schema.rb View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # 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| create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
t.string "record_type", 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" t.index ["tag_id"], name: "index_post_tags_on_tag_id"
end 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| create_table "posts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "title" t.string "title"
t.string "url", limit: 768, null: false 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", "tags"
add_foreign_key "post_tags", "users", column: "created_user_id" add_foreign_key "post_tags", "users", column: "created_user_id"
add_foreign_key "post_tags", "users", column: "deleted_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", "posts", column: "parent_id"
add_foreign_key "posts", "users", column: "uploaded_user_id" add_foreign_key "posts", "users", column: "uploaded_user_id"
add_foreign_key "settings", "users" add_foreign_key "settings", "users"


Loading…
Cancel
Save