diff --git a/backend/app/models/ip_address.rb b/backend/app/models/ip_address.rb index e5e01a3..bf73658 100644 --- a/backend/app/models/ip_address.rb +++ b/backend/app/models/ip_address.rb @@ -2,5 +2,6 @@ class IpAddress < ApplicationRecord validates :ip_address, presence: true, length: { maximum: 16 } validates :banned, inclusion: { in: [true, false] } - has_many :users + has_many :user_ips, dependent: :destroy + has_many :users, through: :user_ips end diff --git a/backend/db/migrate/20260426120600_create_wiki_versions.rb b/backend/db/migrate/20260426120600_create_wiki_versions.rb new file mode 100644 index 0000000..2584962 --- /dev/null +++ b/backend/db/migrate/20260426120600_create_wiki_versions.rb @@ -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 diff --git a/backend/db/schema.rb b/backend/db/schema.rb index ede919d..6e1a67f 100644 --- a/backend/db/schema.rb +++ b/backend/db/schema.rb @@ -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_04_19_035400) do +ActiveRecord::Schema[8.0].define(version: 2026_04_26_120600) 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 @@ -354,6 +354,7 @@ ActiveRecord::Schema[8.0].define(version: 2026_04_19_035400) 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 @@ -396,6 +397,22 @@ ActiveRecord::Schema[8.0].define(version: 2026_04_19_035400) 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" @@ -453,4 +470,6 @@ ActiveRecord::Schema[8.0].define(version: 2026_04_19_035400) 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