This commit is contained in:
2026-02-26 06:48:28 +09:00
parent 3e5eb4687b
commit 663206c14c
3 changed files with 244 additions and 41 deletions
+31 -27
View File
@@ -2,38 +2,46 @@ class PostsController < ApplicationController
Event = Struct.new(:post, :tag, :user, :change_type, :timestamp, keyword_init: true)
def index
url = params[:url].presence
title = params[:title].presence
original_created_from = params[:original_created_from].presence
original_created_to = params[:original_created_to].presence
created_between = params[:created_from].presence, params[:created_to].presence
updated_between = params[:updated_from].presence, params[:updated_to].presence
page = (params[:page].presence || 1).to_i
limit = (params[:limit].presence || 20).to_i
cursor = params[:cursor].presence
page = 1 if page < 1
limit = 1 if limit < 1
offset = (page - 1) * limit
sort_sql =
'COALESCE(posts.original_created_before - INTERVAL 1 SECOND,' +
'posts.original_created_from,' +
'posts.created_at)'
q =
filtered_posts
.preload(tags: { tag_name: :wiki_page })
.with_attached_thumbnail
.select("posts.*, #{ sort_sql } AS sort_ts")
.order(Arel.sql("#{ sort_sql } DESC"))
posts =
if cursor
q.where("#{ sort_sql } < ?", Time.iso8601(cursor)).limit(limit + 1)
else
q.limit(limit).offset(offset)
end
.to_a
next_cursor = nil
if cursor && posts.length > limit
next_cursor = posts.last.read_attribute('sort_ts').iso8601(6)
posts = posts.first(limit)
q = q.where('posts.url LIKE ?', "%#{ url }%") if url
q = q.where('posts.title LIKE ?', "%#{ title }%") if title
if original_created_from
q = q.where('posts.original_created_before > ?', original_created_from)
end
if original_created_to
q = q.where('posts.original_created_from <= ?', original_created_to)
end
q = q.where('posts.created_at >= ?', created_between[0]) if created_between[0]
q = q.where('posts.created_at <= ?', created_between[1]) if created_between[1]
q = q.where('posts.updated_at >= ?', updated_between[0]) if updated_between[0]
q = q.where('posts.updated_at <= ?', updated_between[1]) if updated_between[1]
sort_sql =
'COALESCE(posts.original_created_before - INTERVAL 1 MINUTE,' +
'posts.original_created_from,' +
'posts.created_at)'
posts = q.select("posts.*, #{ sort_sql } AS sort_ts")
.order(Arel.sql("#{ sort_sql } DESC"))
.limit(limit).offset(offset).to_a
render json: { posts: posts.map { |post|
PostRepr.base(post).tap do |json|
@@ -44,11 +52,7 @@ class PostsController < ApplicationController
nil
end
end
}, count: if filtered_posts.group_values.present?
filtered_posts.count.size
else
filtered_posts.count
end, next_cursor: }
}, count: q.group_values.present? ? q.count.size : q.count }
end
def random
@@ -63,7 +67,7 @@ class PostsController < ApplicationController
end
def show
post = Post.includes(tags: { tag_name: :wiki_page }).find(params[:id])
post = Post.includes(tags: { tag_name: :wiki_page }).find_by(id: params[:id])
return head :not_found unless post
viewed = current_user&.viewed?(post) || false
@@ -84,7 +88,7 @@ class PostsController < ApplicationController
title = params[:title].presence
url = params[:url]
thumbnail = params[:thumbnail]
tag_names = params[:tags].to_s.split(' ')
tag_names = params[:tags].to_s.split
original_created_from = params[:original_created_from]
original_created_before = params[:original_created_before]
@@ -125,7 +129,7 @@ class PostsController < ApplicationController
return head :forbidden unless current_user.member?
title = params[:title].presence
tag_names = params[:tags].to_s.split(' ')
tag_names = params[:tags].to_s.split
original_created_from = params[:original_created_from]
original_created_before = params[:original_created_before]
@@ -192,7 +196,7 @@ class PostsController < ApplicationController
private
def filtered_posts
tag_names = params[:tags].to_s.split(' ')
tag_names = params[:tags].to_s.split
match_type = params[:match]
if tag_names.present?
filter_posts_by_tags(tag_names, match_type)