diff --git a/backend/app/controllers/tags_controller.rb b/backend/app/controllers/tags_controller.rb index 3785a9e..7fdcc22 100644 --- a/backend/app/controllers/tags_controller.rb +++ b/backend/app/controllers/tags_controller.rb @@ -302,6 +302,11 @@ class TagsController < ApplicationController NicoTagVersionRecorder.record!(tag:, event_type:, created_by_user:) else TagVersionRecorder.record!(tag:, event_type:, created_by_user:) + if tag.has_wiki + WikiVersionRecorder.record!(page: tag.tag_name.wiki_page, + event_type: :update, + created_by_user:) + end end end diff --git a/backend/app/models/wiki_page.rb b/backend/app/models/wiki_page.rb index 8d3feec..83a7f1b 100644 --- a/backend/app/models/wiki_page.rb +++ b/backend/app/models/wiki_page.rb @@ -13,6 +13,8 @@ class WikiPage < ApplicationRecord foreign_key: :redirect_page_id, dependent: :nullify + has_many :wiki_versions + belongs_to :tag_name validates :tag_name, presence: true diff --git a/backend/app/models/wiki_version.rb b/backend/app/models/wiki_version.rb new file mode 100644 index 0000000..4f55804 --- /dev/null +++ b/backend/app/models/wiki_version.rb @@ -0,0 +1,8 @@ +class WikiVersion < ApplicationRecord + include VersionRecord + + belongs_to :wiki_page + + validates :title, presence: true + validates :body, presence: true +end diff --git a/backend/app/services/wiki/commit.rb b/backend/app/services/wiki/commit.rb index c0be98a..f3e325d 100644 --- a/backend/app/services/wiki/commit.rb +++ b/backend/app/services/wiki/commit.rb @@ -21,7 +21,7 @@ module Wiki end def content! body:, message:, base_revision_id: - normalised = normalise_body(body) + normalised = normalise_body(body).gsub(/\n+$/, '') lines = split_lines(normalised) line_shas = lines.map { |line| Digest::SHA256.hexdigest(line) } @@ -37,10 +37,22 @@ module Wiki current_id = @page.wiki_revisions.maximum(:id) if current_id && current_id != base_revision_id.to_i raise Conflict, - "競合が発生してゐます(現在の Id.:#{ current_id },ベース Id.:#{ base_revision_id })." + "競合が発生してゐます" + + "(現在の Id.:#{ current_id },ベース Id.:#{ base_revision_id })." end end + @page.update!(body: normalised) + + WikiVersionRecorder.record!( + page: { title: @page.title, body: normalised }, + event_type: @page.wiki_versions.exists? ? :update : :create, + created_by_user: @created_user) + tag = @page.tag_name.tag + if tag + TagVersionRecorder.record!(tag:, event_type: :update, created_by_user: @created_user) + end + rev = WikiRevision.create!( wiki_page: @page, base_revision_id:, @@ -54,47 +66,23 @@ module Wiki rows = line_ids.each_with_index.map do |line_id, pos| { wiki_revision_id: rev.id, wiki_line_id: line_id, position: pos } end - WikiRevisionLine.insert_all!(rows) + WikiRevisionLine.insert_all!(rows) if rows.any? rev end end - def redirect! redirect_page:, message:, base_revision_id: - ActiveRecord::Base.transaction do - @page.lock! - - if base_revision_id.present? - current_id = @page.wiki_revisions.maximum(:id) - if current_id && current_id != base_revision_id.to_i - raise Conflict, - "競合が発生してゐます(現在の Id.:#{ current_id },ベース Id.:#{ base_revision_id })." - end - end - - WikiRevision.create!( - wiki_page: @page, - base_revision_id:, - created_user: @created_user, - kind: :redirect, - redirect_page:, - message:, - lines_count: 0, - tree_sha256: nil) - end - end + def redirect!(redirect_page:, message:, base_revision_id:) = raise '廃止しました.' private def normalise_body body s = body.to_s - s.gsub!("\r\n", "\n") + s.gsub!(/\r\n?/, "\n") s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '🖕') end - def split_lines body - body.split("\n") - end + def split_lines(body) = body.split("\n") def upsert_lines! lines, line_shas now = Time.current diff --git a/backend/app/services/wiki_version_recorder.rb b/backend/app/services/wiki_version_recorder.rb new file mode 100644 index 0000000..a9bebe4 --- /dev/null +++ b/backend/app/services/wiki_version_recorder.rb @@ -0,0 +1,17 @@ +class WikiVersionRecorder < VersionRecorder + def self.record! page:, event_type:, created_by_user: + new(page:, event_type:, created_by_user:).record! + end + + def initialize page:, event_type:, created_by_user: + super(record: page, event_type:, created_by_user:) + end + + private + + def version_class = WikiVersion + def version_association = :wiki_versions + def record_key = :wiki_page + + def snapshot_attributes = { title: @record.title, body: @record.body } +end diff --git a/backend/db/migrate/20260426120600_create_wiki_versions.rb b/backend/db/migrate/20260426120600_create_wiki_versions.rb index 2584962..756597f 100644 --- a/backend/db/migrate/20260426120600_create_wiki_versions.rb +++ b/backend/db/migrate/20260426120600_create_wiki_versions.rb @@ -27,7 +27,7 @@ class CreateWikiVersions < ActiveRecord::Migration[8.0] 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.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