This commit is contained in:
2026-05-22 03:29:18 +09:00
parent dc54f9cbb5
commit 7b6b24b9c5
13 changed files with 255 additions and 25 deletions
+50 -17
View File
@@ -95,9 +95,10 @@ class PostsController < ApplicationController
end
def random
post = filtered_posts.preload(tags: [:deerjikists, :materials, { tag_name: :wiki_page }])
.order('RAND()')
.first
post = filtered_posts
.preload(tags: [:deerjikists, :materials, { tag_name: :wiki_page }])
.order('RAND()')
.first
return head :not_found unless post
render json: PostRepr.base(post, current_user)
@@ -108,7 +109,7 @@ class PostsController < ApplicationController
return head :not_found unless post
render json: PostRepr.base(post, current_user)
.merge(tags: build_tag_tree_for(post.tags),
.merge(tags: build_tag_tree_for(post),
related: PostRepr.many(post.related(limit: 20)))
end
@@ -132,11 +133,11 @@ class PostsController < ApplicationController
ApplicationRecord.transaction do
post.save!
tags = Tag.normalise_tags!(tag_names)
Tag.normalise_tags!(tag_names, with_sections: true) => { tags:, sections: }
TagVersioning.record_tag_snapshots!(tags, created_by_user: current_user)
tags = Tag.expand_parent_tags(tags)
sync_post_tags!(post, tags)
sync_post_tags!(post, tags, sections)
sync_parent_posts!(post, parent_post_ids)
@@ -235,7 +236,7 @@ class PostsController < ApplicationController
post.reload
json = PostRepr.base(post, current_user)
json['tags'] = build_tag_tree_for(post.tags)
json['tags'] = build_tag_tree_for(post)
render json:, status: :ok
rescue Tag::NicoTagNormalisationError
head :bad_request
@@ -337,7 +338,7 @@ class PostsController < ApplicationController
def tagged_post_ids_for(name) =
Post.joins(tags: :tag_name).where(tag_names: { name: }).select(:id)
def sync_post_tags! post, desired_tags
def sync_post_tags! post, desired_tags, sections
desired_tags.each do |t|
t.save! if t.new_record?
end
@@ -356,13 +357,20 @@ class PostsController < ApplicationController
end
end
PostTagSection.where(post_id: post.id).destroy_all
sections.each do |tag_id, ranges|
ranges.each do |begin_ms, end_ms|
PostTagSection.create!(post_id: post.id, tag_id:, begin_ms:, end_ms:)
end
end
PostTag.where(post_id: post.id, tag_id: to_remove.to_a).kept.find_each do |pt|
pt.discard_by!(current_user)
end
end
def build_tag_tree_for tags
tags = tags.to_a
def build_tag_tree_for post
tags = post.tags.to_a
tag_ids = tags.map(&:id)
implications = TagImplication.where(parent_tag_id: tag_ids, tag_id: tag_ids)
@@ -384,8 +392,11 @@ class PostsController < ApplicationController
tag = tags_by_id[tag_id]
return nil unless tag
sections = PostTagSection.where(post_id: post.id, tag_id: tag.id)
.as_json(only: [:begin_ms, :end_ms])
if path.include?(tag_id)
return TagRepr.base(tag).merge(children: [])
return TagRepr.base(tag).merge(children: [], sections:)
end
if memo.key?(tag_id)
@@ -397,7 +408,7 @@ class PostsController < ApplicationController
children = child_ids.filter_map { |cid| build_node.(cid, new_path) }
memo[tag_id] = TagRepr.base(tag).merge(children:)
memo[tag_id] = TagRepr.base(tag).merge(children:, sections:)
end
root_ids.filter_map { |id| build_node.call(id, []) }
@@ -470,7 +481,21 @@ class PostsController < ApplicationController
end
def editable_tag_names_from_post post
post.tags.not_nico.joins(:tag_name).order('tag_names.name').pluck('tag_names.name')
post
.post_tags
.kept
.joins(tag: :tag_name)
.merge(Tag.not_nico)
.includes(:sections, tag: :tag_name)
.order('tag_names.name')
.map do |post_tag|
name = post_tag.tag.tag_name.name
sections = post_tag.sections.sort_by(&:begin_ms)
next name if sections.empty?
"#{ name }#{ sections.map { Post.section_literal(_1) }.join }"
end
end
def post_incoming_snapshot title:, original_created_from:, original_created_before:,
@@ -502,9 +527,16 @@ class PostsController < ApplicationController
end
def incoming_tag_names_for_snapshot raw_tag_names
tags = Tag.normalise_tags!(raw_tag_names, with_tagme: false)
Tag.normalise_tags!(raw_tag_names, with_tagme: false, with_sections: true) =>
{ tags:, sections: }
Tag.expand_parent_tags(tags).map(&:name).uniq.sort
Tag.expand_parent_tags(tags).uniq(&:id).map { |tag|
"#{ tag.name }#{ sections[tag.id].to_a.map { section_literal(_1) }.join }"
}.sort
end
def section_literal section
"[#{ Post.ms_to_time(section[0]) }-#{ Post.ms_to_time(section[1]) }]"
end
def post_conflict_json post:, base_version_no:, base_snapshot:,
@@ -591,7 +623,8 @@ class PostsController < ApplicationController
original_created_from: snapshot[:original_created_from],
original_created_before: snapshot[:original_created_before])
editable_tags = Tag.normalise_tags!(snapshot[:tag_names], with_tagme: false)
Tag.normalise_tags!(snapshot[:tag_names], with_tagme: false, with_sections: true) =>
{ tags: editable_tags, sections: }
TagVersioning.record_tag_snapshots!(editable_tags, created_by_user: current_user)
readonly_tags = post.tags.nico.to_a
@@ -599,7 +632,7 @@ class PostsController < ApplicationController
tags = readonly_tags + editable_tags
tags = Tag.expand_parent_tags(tags)
sync_post_tags!(post, tags)
sync_post_tags!(post, tags, sections)
sync_parent_posts!(post, snapshot[:parent_post_ids])
PostVersionRecorder.record!(post:, event_type: :update, created_by_user: current_user)