投稿検索ページ(#206) (#274)
#206 エラー修正 #206 updated_at の並び順修正 Merge remote-tracking branch 'origin/main' into feature/206 Merge branch 'main' into feature/206 Merge branch 'main' into feature/206 Merge branch 'main' into feature/206 #206 #206 #206 #206 #206 #206 タグ補完追加 #206 #206 #206 #206 #206 Merge remote-tracking branch 'origin/main' into feature/206 #206 Co-authored-by: miteruzo <miteruzo@naver.com> Reviewed-on: #274
This commit was merged in pull request #274.
This commit is contained in:
@@ -2,41 +2,88 @@ 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
|
||||
|
||||
order = params[:order].to_s.split(':', 2).map(&:strip)
|
||||
unless order[0].in?(['title', 'url', 'original_created_at', 'created_at', 'updated_at'])
|
||||
order[0] = 'original_created_at'
|
||||
end
|
||||
unless order[1].in?(['asc', 'desc'])
|
||||
order[1] =
|
||||
if order[0].in?(['title', 'url'])
|
||||
'asc'
|
||||
else
|
||||
'desc'
|
||||
end
|
||||
end
|
||||
|
||||
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)'
|
||||
pt_max_sql =
|
||||
PostTag
|
||||
.select('post_id, MAX(updated_at) AS max_updated_at')
|
||||
.group('post_id')
|
||||
.to_sql
|
||||
|
||||
updated_at_all_sql =
|
||||
'GREATEST(posts.updated_at,' +
|
||||
'COALESCE(pt_max.max_updated_at, posts.updated_at))'
|
||||
|
||||
q =
|
||||
filtered_posts
|
||||
.joins("LEFT JOIN (#{ pt_max_sql }) pt_max ON pt_max.post_id = posts.id")
|
||||
.reselect('posts.*', Arel.sql("#{ updated_at_all_sql } AS updated_at_all"))
|
||||
.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]
|
||||
if updated_between[0]
|
||||
q = q.where("#{ updated_at_all_sql } >= ?", updated_between[0])
|
||||
end
|
||||
if updated_between[1]
|
||||
q = q.where("#{ updated_at_all_sql } <= ?", updated_between[1])
|
||||
end
|
||||
|
||||
sort_sql =
|
||||
case order[0]
|
||||
when 'original_created_at'
|
||||
'COALESCE(posts.original_created_before - INTERVAL 1 MINUTE,' +
|
||||
'posts.original_created_from,' +
|
||||
'posts.created_at) '
|
||||
when 'updated_at'
|
||||
updated_at_all_sql
|
||||
else
|
||||
"posts.#{ order[0] }"
|
||||
end
|
||||
posts = q.order(Arel.sql("#{ sort_sql } #{ order[1] }, id #{ order[1] }"))
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
.to_a
|
||||
|
||||
q = q.except(:select, :order)
|
||||
|
||||
render json: { posts: posts.map { |post|
|
||||
PostRepr.base(post).tap do |json|
|
||||
PostRepr.base(post).merge(updated_at: post.updated_at_all).tap do |json|
|
||||
json['thumbnail'] =
|
||||
if post.thumbnail.attached?
|
||||
rails_storage_proxy_url(post.thumbnail, only_path: false)
|
||||
@@ -44,11 +91,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 +106,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 +127,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 +168,7 @@ class PostsController < ApplicationController
|
||||
return head :forbidden unless current_user.gte_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 +235,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)
|
||||
|
||||
Reference in New Issue
Block a user