Merge remote-tracking branch 'origin/main' into feature/047
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
class CreateMaterials < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :materials do |t|
|
||||
t.string :url
|
||||
t.references :parent, index: true, foreign_key: { to_table: :materials }
|
||||
t.references :tag, index: true, foreign_key: true
|
||||
t.references :created_by_user, foreign_key: { to_table: :users }
|
||||
t.references :updated_by_user, foreign_key: { to_table: :users }
|
||||
t.timestamps
|
||||
t.datetime :discarded_at, index: true
|
||||
t.virtual :active_url, type: :string,
|
||||
as: 'IF(discarded_at IS NULL, url, NULL)',
|
||||
stored: false
|
||||
|
||||
t.index :active_url, unique: true
|
||||
end
|
||||
|
||||
create_table :material_versions do |t|
|
||||
t.references :material, null: false, foreign_key: true
|
||||
t.integer :version_no, null: false
|
||||
t.string :url, index: true
|
||||
t.references :parent, index: true, foreign_key: { to_table: :materials }
|
||||
t.references :tag, index: true, foreign_key: true
|
||||
t.references :created_by_user, foreign_key: { to_table: :users }
|
||||
t.references :updated_by_user, foreign_key: { to_table: :users }
|
||||
t.timestamps
|
||||
t.datetime :discarded_at, index: true
|
||||
|
||||
t.index [:material_id, :version_no],
|
||||
unique: true,
|
||||
name: 'index_material_versions_on_material_id_and_version_no'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,203 @@
|
||||
require 'set'
|
||||
|
||||
|
||||
class CreatePostVersions < ActiveRecord::Migration[8.0]
|
||||
class Post < ActiveRecord::Base
|
||||
self.table_name = 'posts'
|
||||
end
|
||||
|
||||
class PostTag < ActiveRecord::Base
|
||||
self.table_name = 'post_tags'
|
||||
end
|
||||
|
||||
class PostVersion < ActiveRecord::Base
|
||||
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
|
||||
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.references :parent, foreign_key: { to_table: :posts }
|
||||
t.datetime :original_created_from
|
||||
t.datetime :original_created_before
|
||||
t.datetime :created_at, null: false
|
||||
t.references :created_by_user, foreign_key: { to_table: :users }
|
||||
|
||||
t.index [:post_id, :version_no], unique: true
|
||||
t.check_constraint 'version_no > 0',
|
||||
name: 'post_versions_version_no_positive'
|
||||
t.check_constraint "event_type IN ('create', 'update', 'discard', 'restore')",
|
||||
name: 'post_versions_event_type_valid'
|
||||
end
|
||||
|
||||
PostVersion.reset_column_information
|
||||
|
||||
say_with_time 'Backfilling post_versions' do
|
||||
Post.find_in_batches(batch_size: 500) do |posts|
|
||||
post_ids = posts.map(&:id)
|
||||
|
||||
post_tag_rows_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)
|
||||
.pluck('post_tags.post_id',
|
||||
'post_tags.created_at',
|
||||
'post_tags.discarded_at',
|
||||
'post_tags.created_user_id',
|
||||
'post_tags.deleted_user_id',
|
||||
'tag_names.name')
|
||||
.each_with_object(Hash.new { |h, k| h[k] = [] }) do |row, h|
|
||||
post_id, created_at, discarded_at, created_user_id, deleted_user_id, tag_name = row
|
||||
h[post_id] << { created_at:,
|
||||
discarded_at:,
|
||||
created_user_id:,
|
||||
deleted_user_id:,
|
||||
tag_name: }
|
||||
end
|
||||
|
||||
rows = []
|
||||
|
||||
posts.each do |post|
|
||||
post_tag_rows = post_tag_rows_by_post_id[post.id]
|
||||
|
||||
events = post_tag_rows.flat_map do |post_tag_row|
|
||||
ary = [[post_tag_row[:created_at],
|
||||
post_tag_row[:created_user_id],
|
||||
:add,
|
||||
post_tag_row[:tag_name]]]
|
||||
|
||||
if post_tag_row[:discarded_at]
|
||||
ary << [post_tag_row[:discarded_at],
|
||||
post_tag_row[:deleted_user_id],
|
||||
:remove,
|
||||
post_tag_row[:tag_name]]
|
||||
end
|
||||
|
||||
ary
|
||||
end
|
||||
|
||||
kind_order = { add: 0, remove: 1 }
|
||||
|
||||
events.sort_by! do |event_at, user_id, kind, tag_name|
|
||||
[event_at, user_id || 0, kind_order.fetch(kind), tag_name]
|
||||
end
|
||||
|
||||
event_buckets = bucket_events(events)
|
||||
|
||||
active_tags = Set.new
|
||||
version_no = 0
|
||||
|
||||
if event_buckets.empty?
|
||||
version_no += 1
|
||||
rows << build_row(post:,
|
||||
version_no:,
|
||||
event_type: 'create',
|
||||
created_at: post.created_at,
|
||||
created_by_user_id: post.uploaded_user_id,
|
||||
tags: [])
|
||||
next
|
||||
end
|
||||
|
||||
first_bucket = event_buckets.first
|
||||
merge_first_bucket_into_create = first_bucket[:first_at] <= post.created_at + 1.second
|
||||
|
||||
if merge_first_bucket_into_create
|
||||
event_buckets.shift
|
||||
apply_bucket!(active_tags, first_bucket)
|
||||
|
||||
version_no += 1
|
||||
rows << build_row(
|
||||
post:,
|
||||
version_no:,
|
||||
event_type: 'create',
|
||||
created_at: post.created_at,
|
||||
created_by_user_id: post.uploaded_user_id || first_bucket[:user_ids].compact.first,
|
||||
tags: active_tags.to_a.sort)
|
||||
else
|
||||
version_no += 1
|
||||
rows << build_row(
|
||||
post:,
|
||||
version_no:,
|
||||
event_type: 'create',
|
||||
created_at: post.created_at,
|
||||
created_by_user_id: post.uploaded_user_id,
|
||||
tags: [])
|
||||
end
|
||||
|
||||
event_buckets.each do |bucket|
|
||||
apply_bucket!(active_tags, bucket)
|
||||
|
||||
version_no += 1
|
||||
rows << build_row(
|
||||
post:,
|
||||
version_no:,
|
||||
event_type: 'update',
|
||||
created_at: bucket[:first_at],
|
||||
created_by_user_id: bucket[:user_ids].compact.first,
|
||||
tags: active_tags.to_a.sort)
|
||||
end
|
||||
end
|
||||
|
||||
PostVersion.insert_all!(rows) if rows.any?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :post_versions
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def bucket_events events
|
||||
buckets = []
|
||||
|
||||
events.each do |event_at, user_id, kind, tag_name|
|
||||
if buckets.empty? || event_at - buckets.last[:last_at] > 1.second
|
||||
buckets << { first_at: event_at,
|
||||
last_at: event_at,
|
||||
user_ids: [user_id],
|
||||
events: [[kind, tag_name]] }
|
||||
else
|
||||
bucket = buckets.last
|
||||
bucket[:last_at] = event_at
|
||||
bucket[:user_ids] << user_id
|
||||
bucket[:events] << [kind, tag_name]
|
||||
end
|
||||
end
|
||||
|
||||
buckets
|
||||
end
|
||||
|
||||
def apply_bucket! active_tags, bucket
|
||||
bucket[:events].each do |kind, tag_name|
|
||||
if kind == :add
|
||||
active_tags.add(tag_name)
|
||||
else
|
||||
active_tags.delete(tag_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def build_row post:, version_no:, event_type:, created_at:, created_by_user_id:, tags:
|
||||
{ post_id: post.id,
|
||||
version_no:,
|
||||
event_type:,
|
||||
title: post.title,
|
||||
url: post.url,
|
||||
thumbnail_base: post.thumbnail_base,
|
||||
tags: tags.join(' '),
|
||||
parent_id: post.parent_id,
|
||||
original_created_from: post.original_created_from,
|
||||
original_created_before: post.original_created_before,
|
||||
created_at:,
|
||||
created_by_user_id: }
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,156 @@
|
||||
class CreateTagVersions < ActiveRecord::Migration[8.0]
|
||||
class Tag < ActiveRecord::Base
|
||||
self.table_name = 'tags'
|
||||
end
|
||||
|
||||
class TagName < ActiveRecord::Base
|
||||
self.table_name = 'tag_names'
|
||||
end
|
||||
|
||||
class TagImplication < ActiveRecord::Base
|
||||
self.table_name = 'tag_implications'
|
||||
end
|
||||
|
||||
class TagVersion < ActiveRecord::Base
|
||||
self.table_name = 'tag_versions'
|
||||
end
|
||||
|
||||
class NicoTagVersion < ActiveRecord::Base
|
||||
self.table_name = 'nico_tag_versions'
|
||||
end
|
||||
|
||||
class NicoTagRelation < ActiveRecord::Base
|
||||
self.table_name = 'nico_tag_relations'
|
||||
end
|
||||
|
||||
def up
|
||||
create_table :tag_versions do |t|
|
||||
t.references :tag, null: false, foreign_key: true, index: false
|
||||
t.integer :version_no, null: false
|
||||
t.string :event_type, null: false
|
||||
t.string :name, null: false
|
||||
t.string :category, null: false
|
||||
t.text :aliases, null: false
|
||||
t.text :parent_tag_ids, null: false
|
||||
t.datetime :created_at, null: false
|
||||
t.references :created_by_user, foreign_key: { to_table: :users }, index: false
|
||||
|
||||
t.index [:tag_id, :version_no], unique: true
|
||||
t.index :created_at
|
||||
t.index [:tag_id, :created_at], order: { created_at: :desc }
|
||||
t.index [:created_by_user_id, :created_at], order: { created_at: :desc }
|
||||
t.check_constraint 'version_no > 0',
|
||||
name: 'tag_versions_version_no_positive'
|
||||
end
|
||||
|
||||
create_table :nico_tag_versions do |t|
|
||||
t.references :tag, null: false, foreign_key: true, index: false
|
||||
t.integer :version_no, null: false
|
||||
t.string :event_type, null: false
|
||||
t.string :name, null: false
|
||||
t.text :linked_tags, null: false
|
||||
t.datetime :created_at, null: false
|
||||
t.references :created_by_user, foreign_key: { to_table: :users }, index: false
|
||||
|
||||
t.index [:tag_id, :version_no], unique: true
|
||||
t.index :created_at
|
||||
t.index [:tag_id, :created_at], order: { created_at: :desc }
|
||||
t.index [:created_by_user_id, :created_at], order: { created_at: :desc }
|
||||
t.check_constraint 'version_no > 0',
|
||||
name: 'nico_tag_versions_version_no_positive'
|
||||
end
|
||||
|
||||
TagVersion.reset_column_information
|
||||
say_with_time 'Backfilling tag_versions' do
|
||||
Tag.where(discarded_at: nil)
|
||||
.where.not(category: 'nico')
|
||||
.find_in_batches(batch_size: 500) do |tags|
|
||||
tag_ids = tags.map(&:id)
|
||||
|
||||
tag_implication_rows_by_tag_id =
|
||||
TagImplication
|
||||
.where(tag_id: tag_ids)
|
||||
.pluck(:tag_id, :parent_tag_id)
|
||||
.each_with_object(Hash.new { |h, k| h[k] = [] }) do |row, h|
|
||||
h[row[0]] << row[1]
|
||||
end
|
||||
|
||||
tag_name_rows_by_tag_id =
|
||||
TagName
|
||||
.joins('INNER JOIN tags ON tags.tag_name_id = tag_names.id')
|
||||
.where(tags: { id: tag_ids })
|
||||
.pluck('tags.id', 'tag_names.name')
|
||||
.each_with_object({ }) do |row, h|
|
||||
h[row[0]] = row[1]
|
||||
end
|
||||
|
||||
tag_alias_rows_by_tag_id =
|
||||
TagName
|
||||
.joins('INNER JOIN tags ON tags.tag_name_id = tag_names.canonical_id')
|
||||
.where(tags: { id: tag_ids })
|
||||
.where(tag_names: { discarded_at: nil })
|
||||
.pluck('tags.id', 'tag_names.name')
|
||||
.each_with_object(Hash.new { |h, k| h[k] = [] }) do |row, h|
|
||||
h[row[0]] << row[1]
|
||||
end
|
||||
|
||||
TagVersion.insert_all(tags.map { |tag|
|
||||
{ tag_id: tag.id,
|
||||
version_no: 1,
|
||||
event_type: 'create',
|
||||
name: tag_name_rows_by_tag_id[tag.id],
|
||||
category: tag.category,
|
||||
aliases: tag_alias_rows_by_tag_id[tag.id].sort.join(' '),
|
||||
parent_tag_ids: tag_implication_rows_by_tag_id[tag.id].sort.join(' '),
|
||||
created_at: tag.created_at,
|
||||
created_by_user_id: nil }
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
NicoTagVersion.reset_column_information
|
||||
say_with_time 'Backfilling nico_tag_versions' do
|
||||
Tag.where(discarded_at: nil, category: 'nico')
|
||||
.find_in_batches(batch_size: 500) do |tags|
|
||||
tag_ids = tags.map(&:id)
|
||||
|
||||
tag_name_rows_by_tag_id =
|
||||
TagName
|
||||
.joins('INNER JOIN tags ON tags.tag_name_id = tag_names.id')
|
||||
.where(tags: { id: tag_ids })
|
||||
.pluck('tags.id', 'tag_names.name')
|
||||
.each_with_object({ }) do |row, h|
|
||||
h[row[0]] = row[1]
|
||||
end
|
||||
|
||||
nico_tag_relation_rows_by_tag_id =
|
||||
NicoTagRelation
|
||||
.joins('INNER JOIN tags nico_tags ON nico_tags.id = nico_tag_relations.nico_tag_id')
|
||||
.joins('INNER JOIN tags linked_tags ON linked_tags.id = nico_tag_relations.tag_id')
|
||||
.joins('INNER JOIN tag_names ON tag_names.id = linked_tags.tag_name_id')
|
||||
.where(nico_tags: { id: tag_ids })
|
||||
.where(linked_tags: { discarded_at: nil })
|
||||
.where(tag_names: { discarded_at: nil })
|
||||
.pluck('nico_tags.id', 'tag_names.name')
|
||||
.each_with_object(Hash.new { |h, k| h[k] = [] }) do |row, h|
|
||||
h[row[0]] << row[1]
|
||||
end
|
||||
|
||||
NicoTagVersion.insert_all(tags.map { |tag|
|
||||
{ tag_id: tag.id,
|
||||
version_no: 1,
|
||||
event_type: 'create',
|
||||
name: tag_name_rows_by_tag_id[tag.id],
|
||||
linked_tags: nico_tag_relation_rows_by_tag_id[tag.id].sort.join(' '),
|
||||
created_at: tag.created_at,
|
||||
created_by_user_id: nil }
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :nico_tag_versions
|
||||
drop_table :tag_versions
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,91 @@
|
||||
class CreateWikiVersions < ActiveRecord::Migration[8.0]
|
||||
class WikiPage < ActiveRecord::Base
|
||||
self.table_name = 'wiki_pages'
|
||||
end
|
||||
|
||||
class WikiRevision < ActiveRecord::Base
|
||||
self.table_name = 'wiki_revisions'
|
||||
end
|
||||
|
||||
class WikiRevisionLine < ActiveRecord::Base
|
||||
self.table_name = 'wiki_revision_lines'
|
||||
end
|
||||
|
||||
class WikiLine < ActiveRecord::Base
|
||||
self.table_name = 'wiki_lines'
|
||||
end
|
||||
|
||||
class WikiVersion < ActiveRecord::Base
|
||||
self.table_name = 'wiki_versions'
|
||||
end
|
||||
|
||||
class TagName < ActiveRecord::Base
|
||||
self.table_name = 'tag_names'
|
||||
end
|
||||
|
||||
def up
|
||||
add_column :wiki_pages, :body, :text, after: :tag_name_id
|
||||
|
||||
create_table :wiki_versions do |t|
|
||||
t.references :wiki_page, null: false, foreign_key: true
|
||||
t.integer :version_no, null: false
|
||||
t.string :event_type, null: false
|
||||
t.string :title, null: false
|
||||
t.text :body, null: false
|
||||
t.text :reason
|
||||
t.datetime :created_at, null: false
|
||||
t.references :created_by_user, foreign_key: { to_table: :users }
|
||||
|
||||
t.index [:wiki_page_id, :version_no], unique: true
|
||||
t.check_constraint 'version_no > 0',
|
||||
name: 'wiki_versions_version_no_positive'
|
||||
t.check_constraint "event_type IN ('create', 'update', 'discard', 'restore')",
|
||||
name: 'wiki_versions_event_type_valid'
|
||||
end
|
||||
|
||||
WikiPage.reset_column_information
|
||||
WikiVersion.reset_column_information
|
||||
|
||||
say_with_time 'Backfilling wiki_versions' do
|
||||
WikiPage.find_each do |page|
|
||||
base_revision_id = nil
|
||||
version_no = 1
|
||||
title = TagName.find(page.tag_name_id).name
|
||||
body = nil
|
||||
loop do
|
||||
rev = WikiRevision.where(wiki_page_id: page.id).find_by(base_revision_id:)
|
||||
break unless rev
|
||||
|
||||
body = WikiRevisionLine.where(wiki_revision_id: rev.id).order(:position).map { |wrl|
|
||||
WikiLine.find(wrl.wiki_line_id).body
|
||||
}.join("\n")
|
||||
|
||||
WikiVersion.create!(
|
||||
wiki_page_id: page.id,
|
||||
version_no:,
|
||||
event_type: version_no == 1 ? 'create' : 'update',
|
||||
title:,
|
||||
body:,
|
||||
reason: rev.message,
|
||||
created_at: rev.created_at,
|
||||
created_by_user_id: rev.created_user_id)
|
||||
|
||||
version_no += 1
|
||||
base_revision_id = rev.id
|
||||
end
|
||||
if body
|
||||
page.update!(body:)
|
||||
else
|
||||
page.destroy!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
change_column_null :wiki_pages, :body, false
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :wiki_versions
|
||||
remove_column :wiki_pages, :body
|
||||
end
|
||||
end
|
||||
Generated
+141
-6
@@ -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_23_192300) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2026_05_01_153900) 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
|
||||
@@ -50,12 +50,52 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) do
|
||||
|
||||
create_table "ip_addresses", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.binary "ip_address", limit: 16, null: false
|
||||
t.boolean "banned", default: false, null: false
|
||||
t.datetime "banned_at"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["banned_at"], name: "index_ip_addresses_on_banned_at"
|
||||
t.index ["ip_address"], name: "index_ip_addresses_on_ip_address", unique: true
|
||||
end
|
||||
|
||||
create_table "material_versions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "material_id", null: false
|
||||
t.integer "version_no", null: false
|
||||
t.string "url"
|
||||
t.bigint "parent_id"
|
||||
t.bigint "tag_id"
|
||||
t.bigint "created_by_user_id"
|
||||
t.bigint "updated_by_user_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "discarded_at"
|
||||
t.index ["created_by_user_id"], name: "index_material_versions_on_created_by_user_id"
|
||||
t.index ["discarded_at"], name: "index_material_versions_on_discarded_at"
|
||||
t.index ["material_id", "version_no"], name: "index_material_versions_on_material_id_and_version_no", unique: true
|
||||
t.index ["material_id"], name: "index_material_versions_on_material_id"
|
||||
t.index ["parent_id"], name: "index_material_versions_on_parent_id"
|
||||
t.index ["tag_id"], name: "index_material_versions_on_tag_id"
|
||||
t.index ["updated_by_user_id"], name: "index_material_versions_on_updated_by_user_id"
|
||||
t.index ["url"], name: "index_material_versions_on_url"
|
||||
end
|
||||
|
||||
create_table "materials", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.string "url"
|
||||
t.bigint "parent_id"
|
||||
t.bigint "tag_id"
|
||||
t.bigint "created_by_user_id"
|
||||
t.bigint "updated_by_user_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "discarded_at"
|
||||
t.virtual "active_url", type: :string, as: "if((`discarded_at` is null),`url`,NULL)"
|
||||
t.index ["active_url"], name: "index_materials_on_active_url", unique: true
|
||||
t.index ["created_by_user_id"], name: "index_materials_on_created_by_user_id"
|
||||
t.index ["discarded_at"], name: "index_materials_on_discarded_at"
|
||||
t.index ["parent_id"], name: "index_materials_on_parent_id"
|
||||
t.index ["tag_id"], name: "index_materials_on_tag_id"
|
||||
t.index ["updated_by_user_id"], name: "index_materials_on_updated_by_user_id"
|
||||
end
|
||||
|
||||
create_table "nico_tag_relations", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "nico_tag_id", null: false
|
||||
t.bigint "tag_id", null: false
|
||||
@@ -65,6 +105,30 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) do
|
||||
t.index ["tag_id"], name: "index_nico_tag_relations_on_tag_id"
|
||||
end
|
||||
|
||||
create_table "nico_tag_versions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "tag_id", null: false
|
||||
t.integer "version_no", null: false
|
||||
t.string "event_type", null: false
|
||||
t.string "name", null: false
|
||||
t.text "linked_tags", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "created_by_user_id"
|
||||
t.index ["created_at"], name: "index_nico_tag_versions_on_created_at"
|
||||
t.index ["created_by_user_id", "created_at"], name: "index_nico_tag_versions_on_created_by_user_id_and_created_at", order: { created_at: :desc }
|
||||
t.index ["tag_id", "created_at"], name: "index_nico_tag_versions_on_tag_id_and_created_at", order: { created_at: :desc }
|
||||
t.index ["tag_id", "version_no"], name: "index_nico_tag_versions_on_tag_id_and_version_no", unique: true
|
||||
t.check_constraint "`version_no` > 0", name: "nico_tag_versions_version_no_positive"
|
||||
end
|
||||
|
||||
create_table "post_implications", primary_key: ["post_id", "parent_post_id"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "post_id", null: false
|
||||
t.bigint "parent_post_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["parent_post_id"], name: "index_post_implications_on_parent_post_id"
|
||||
t.check_constraint "`post_id` <> `parent_post_id`", name: "chk_post_implications_no_self"
|
||||
end
|
||||
|
||||
create_table "post_similarities", primary_key: ["post_id", "target_post_id"], charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "post_id", null: false
|
||||
t.bigint "target_post_id", null: false
|
||||
@@ -93,17 +157,35 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) 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.text "parent_post_ids", null: false
|
||||
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 ["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')", name: "post_versions_event_type_valid"
|
||||
t.check_constraint "`version_no` > 0", name: "post_versions_version_no_positive"
|
||||
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
|
||||
t.string "thumbnail_base", limit: 2000
|
||||
t.bigint "parent_id"
|
||||
t.bigint "uploaded_user_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "original_created_from"
|
||||
t.datetime "original_created_before"
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["parent_id"], name: "index_posts_on_parent_id"
|
||||
t.index ["uploaded_user_id"], name: "index_posts_on_uploaded_user_id"
|
||||
t.index ["url"], name: "index_posts_on_url", unique: true
|
||||
end
|
||||
@@ -156,6 +238,23 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) do
|
||||
t.index ["target_tag_id"], name: "index_tag_similarities_on_target_tag_id"
|
||||
end
|
||||
|
||||
create_table "tag_versions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "tag_id", null: false
|
||||
t.integer "version_no", null: false
|
||||
t.string "event_type", null: false
|
||||
t.string "name", null: false
|
||||
t.string "category", null: false
|
||||
t.text "aliases", null: false
|
||||
t.text "parent_tag_ids", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "created_by_user_id"
|
||||
t.index ["created_at"], name: "index_tag_versions_on_created_at"
|
||||
t.index ["created_by_user_id", "created_at"], name: "index_tag_versions_on_created_by_user_id_and_created_at", order: { created_at: :desc }
|
||||
t.index ["tag_id", "created_at"], name: "index_tag_versions_on_tag_id_and_created_at", order: { created_at: :desc }
|
||||
t.index ["tag_id", "version_no"], name: "index_tag_versions_on_tag_id_and_version_no", unique: true
|
||||
t.check_constraint "`version_no` > 0", name: "tag_versions_version_no_positive"
|
||||
end
|
||||
|
||||
create_table "tags", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "tag_name_id", null: false
|
||||
t.string "category", default: "general", null: false
|
||||
@@ -234,9 +333,10 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) do
|
||||
t.string "name"
|
||||
t.string "inheritance_code", limit: 64, null: false
|
||||
t.string "role", null: false
|
||||
t.boolean "banned", default: false, null: false
|
||||
t.datetime "banned_at"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["banned_at"], name: "index_users_on_banned_at"
|
||||
end
|
||||
|
||||
create_table "wiki_assets", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
@@ -262,6 +362,7 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) do
|
||||
|
||||
create_table "wiki_pages", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "tag_name_id", null: false
|
||||
t.text "body", null: false
|
||||
t.bigint "created_user_id", null: false
|
||||
t.bigint "updated_user_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
@@ -304,17 +405,47 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) do
|
||||
t.index ["wiki_page_id"], name: "index_wiki_revisions_on_wiki_page_id"
|
||||
end
|
||||
|
||||
create_table "wiki_versions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
|
||||
t.bigint "wiki_page_id", null: false
|
||||
t.integer "version_no", null: false
|
||||
t.string "event_type", null: false
|
||||
t.string "title", null: false
|
||||
t.text "body", null: false
|
||||
t.text "reason"
|
||||
t.datetime "created_at", null: false
|
||||
t.bigint "created_by_user_id"
|
||||
t.index ["created_by_user_id"], name: "index_wiki_versions_on_created_by_user_id"
|
||||
t.index ["wiki_page_id", "version_no"], name: "index_wiki_versions_on_wiki_page_id_and_version_no", unique: true
|
||||
t.index ["wiki_page_id"], name: "index_wiki_versions_on_wiki_page_id"
|
||||
t.check_constraint "`event_type` in (_utf8mb4'create',_utf8mb4'update',_utf8mb4'discard',_utf8mb4'restore')", name: "wiki_versions_event_type_valid"
|
||||
t.check_constraint "`version_no` > 0", name: "wiki_versions_version_no_positive"
|
||||
end
|
||||
|
||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "material_versions", "materials"
|
||||
add_foreign_key "material_versions", "materials", column: "parent_id"
|
||||
add_foreign_key "material_versions", "tags"
|
||||
add_foreign_key "material_versions", "users", column: "created_by_user_id"
|
||||
add_foreign_key "material_versions", "users", column: "updated_by_user_id"
|
||||
add_foreign_key "materials", "materials", column: "parent_id"
|
||||
add_foreign_key "materials", "tags"
|
||||
add_foreign_key "materials", "users", column: "created_by_user_id"
|
||||
add_foreign_key "materials", "users", column: "updated_by_user_id"
|
||||
add_foreign_key "nico_tag_relations", "tags"
|
||||
add_foreign_key "nico_tag_relations", "tags", column: "nico_tag_id"
|
||||
add_foreign_key "nico_tag_versions", "tags"
|
||||
add_foreign_key "nico_tag_versions", "users", column: "created_by_user_id"
|
||||
add_foreign_key "post_implications", "posts"
|
||||
add_foreign_key "post_implications", "posts", column: "parent_post_id"
|
||||
add_foreign_key "post_similarities", "posts"
|
||||
add_foreign_key "post_similarities", "posts", column: "target_post_id"
|
||||
add_foreign_key "post_tags", "posts"
|
||||
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 "posts", "posts", column: "parent_id"
|
||||
add_foreign_key "post_versions", "posts"
|
||||
add_foreign_key "post_versions", "users", column: "created_by_user_id"
|
||||
add_foreign_key "posts", "users", column: "uploaded_user_id"
|
||||
add_foreign_key "settings", "users"
|
||||
add_foreign_key "tag_implications", "tags"
|
||||
@@ -322,6 +453,8 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) do
|
||||
add_foreign_key "tag_names", "tag_names", column: "canonical_id"
|
||||
add_foreign_key "tag_similarities", "tags"
|
||||
add_foreign_key "tag_similarities", "tags", column: "target_tag_id"
|
||||
add_foreign_key "tag_versions", "tags"
|
||||
add_foreign_key "tag_versions", "users", column: "created_by_user_id"
|
||||
add_foreign_key "tags", "tag_names"
|
||||
add_foreign_key "theatre_comments", "theatres"
|
||||
add_foreign_key "theatre_comments", "users"
|
||||
@@ -345,4 +478,6 @@ ActiveRecord::Schema[8.0].define(version: 2026_03_23_192300) do
|
||||
add_foreign_key "wiki_revisions", "wiki_pages"
|
||||
add_foreign_key "wiki_revisions", "wiki_pages", column: "redirect_page_id"
|
||||
add_foreign_key "wiki_revisions", "wiki_revisions", column: "base_revision_id"
|
||||
add_foreign_key "wiki_versions", "users", column: "created_by_user_id"
|
||||
add_foreign_key "wiki_versions", "wiki_pages"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user