Merge pull request #4007 from evazion/fix-4004
Fix #4004: Add additional order by metatags for posts
This commit is contained in:
@@ -19,7 +19,7 @@ class ArtistCommentary < ApplicationRecord
|
||||
end
|
||||
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post)).reorder("")
|
||||
where(post_id: PostQueryBuilder.new(query).build.reorder(""))
|
||||
end
|
||||
|
||||
def deleted
|
||||
|
||||
@@ -52,7 +52,7 @@ class Comment < ApplicationRecord
|
||||
end
|
||||
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post)).reorder("")
|
||||
where(post_id: PostQueryBuilder.new(query).build.reorder(""))
|
||||
end
|
||||
|
||||
def for_creator(user_id)
|
||||
|
||||
@@ -18,7 +18,7 @@ class Note < ApplicationRecord
|
||||
end
|
||||
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post)).reorder("")
|
||||
where(post_id: PostQueryBuilder.new(query).build.reorder(""))
|
||||
end
|
||||
|
||||
def for_creator(user_id)
|
||||
|
||||
@@ -1609,6 +1609,79 @@ class Post < ApplicationRecord
|
||||
joins("CROSS JOIN unnest(string_to_array(tag_string, ' ')) AS tag")
|
||||
end
|
||||
|
||||
def with_comment_stats
|
||||
relation = left_outer_joins(:comments).group(:id).select("posts.*")
|
||||
relation = relation.select("COUNT(comments.id) AS comment_count")
|
||||
relation = relation.select("COUNT(comments.id) FILTER (WHERE comments.is_deleted = TRUE) AS deleted_comment_count")
|
||||
relation = relation.select("COUNT(comments.id) FILTER (WHERE comments.is_deleted = FALSE) AS active_comment_count")
|
||||
relation
|
||||
end
|
||||
|
||||
def with_note_stats
|
||||
relation = left_outer_joins(:notes).group(:id).select("posts.*")
|
||||
relation = relation.select("COUNT(notes.id) AS note_count")
|
||||
relation = relation.select("COUNT(notes.id) FILTER (WHERE notes.is_active = TRUE) AS active_note_count")
|
||||
relation = relation.select("COUNT(notes.id) FILTER (WHERE notes.is_active = FALSE) AS deleted_note_count")
|
||||
relation
|
||||
end
|
||||
|
||||
def with_flag_stats
|
||||
relation = left_outer_joins(:flags).group(:id).select("posts.*")
|
||||
relation = relation.select("COUNT(post_flags.id) AS flag_count")
|
||||
relation = relation.select("COUNT(post_flags.id) FILTER (WHERE post_flags.is_resolved = TRUE) AS resolved_flag_count")
|
||||
relation = relation.select("COUNT(post_flags.id) FILTER (WHERE post_flags.is_resolved = FALSE) AS unresolved_flag_count")
|
||||
relation
|
||||
end
|
||||
|
||||
def with_appeal_stats
|
||||
relation = left_outer_joins(:appeals).group(:id).select("posts.*")
|
||||
relation = relation.select("COUNT(post_appeals.id) AS appeal_count")
|
||||
relation
|
||||
end
|
||||
|
||||
def with_approval_stats
|
||||
relation = left_outer_joins(:approvals).group(:id).select("posts.*")
|
||||
relation = relation.select("COUNT(post_approvals.id) AS approval_count")
|
||||
relation
|
||||
end
|
||||
|
||||
def with_replacement_stats
|
||||
relation = left_outer_joins(:replacements).group(:id).select("posts.*")
|
||||
relation = relation.select("COUNT(post_replacements.id) AS replacement_count")
|
||||
relation
|
||||
end
|
||||
|
||||
def with_child_stats
|
||||
relation = left_outer_joins(:children).group(:id).select("posts.*")
|
||||
relation = relation.select("COUNT(children_posts.id) AS child_count")
|
||||
relation = relation.select("COUNT(children_posts.id) FILTER (WHERE children_posts.is_deleted = TRUE) AS deleted_child_count")
|
||||
relation = relation.select("COUNT(children_posts.id) FILTER (WHERE children_posts.is_deleted = FALSE) AS active_child_count")
|
||||
relation
|
||||
end
|
||||
|
||||
def with_pool_stats
|
||||
pool_posts = Pool.joins("CROSS JOIN unnest(post_ids) AS post_id").select(:id, :is_deleted, :category, "post_id")
|
||||
relation = joins("LEFT OUTER JOIN (#{pool_posts.to_sql}) pools ON pools.post_id = posts.id").group(:id).select("posts.*")
|
||||
|
||||
relation = relation.select("COUNT(pools.id) AS pool_count")
|
||||
relation = relation.select("COUNT(pools.id) FILTER (WHERE pools.is_deleted = TRUE) AS deleted_pool_count")
|
||||
relation = relation.select("COUNT(pools.id) FILTER (WHERE pools.is_deleted = FALSE) AS active_pool_count")
|
||||
relation = relation.select("COUNT(pools.id) FILTER (WHERE pools.category = 'series') AS series_pool_count")
|
||||
relation = relation.select("COUNT(pools.id) FILTER (WHERE pools.category = 'collection') AS collection_pool_count")
|
||||
relation
|
||||
end
|
||||
|
||||
def with_stats(tables)
|
||||
return all if tables.empty?
|
||||
|
||||
relation = all
|
||||
tables.each do |table|
|
||||
relation = relation.send("with_#{table}_stats")
|
||||
end
|
||||
|
||||
from(relation.arel.as("posts"))
|
||||
end
|
||||
|
||||
def pending
|
||||
where(is_pending: true)
|
||||
end
|
||||
@@ -1662,7 +1735,7 @@ class Post < ApplicationRecord
|
||||
|
||||
if read_only
|
||||
begin
|
||||
PostQueryBuilder.new(query).build(PostReadOnly.where("true"))
|
||||
PostQueryBuilder.new(query, read_only: true).build
|
||||
rescue PG::ConnectionBad
|
||||
PostQueryBuilder.new(query).build
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ class PostAppeal < ApplicationRecord
|
||||
|
||||
module SearchMethods
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post))
|
||||
where(post_id: PostQueryBuilder.new(query).build.reorder(""))
|
||||
end
|
||||
|
||||
def resolved
|
||||
|
||||
@@ -35,7 +35,7 @@ class PostApproval < ApplicationRecord
|
||||
concerning :SearchMethods do
|
||||
class_methods do
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post))
|
||||
where(post_id: PostQueryBuilder.new(query).build.reorder(""))
|
||||
end
|
||||
|
||||
def search(params)
|
||||
|
||||
@@ -33,7 +33,7 @@ class PostFlag < ApplicationRecord
|
||||
end
|
||||
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post))
|
||||
where(post_id: PostQueryBuilder.new(query).build.reorder(""))
|
||||
end
|
||||
|
||||
def resolved
|
||||
|
||||
@@ -21,7 +21,7 @@ class PostReplacement < ApplicationRecord
|
||||
concerning :Search do
|
||||
class_methods do
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post))
|
||||
where(post_id: PostQueryBuilder.new(query).build.reorder(""))
|
||||
end
|
||||
|
||||
def search(params = {})
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
class Tag < ApplicationRecord
|
||||
COSINE_SIMILARITY_RELATED_TAG_THRESHOLD = 300
|
||||
COUNT_METATAGS = %w[
|
||||
comment_count deleted_comment_count active_comment_count
|
||||
note_count deleted_note_count active_note_count
|
||||
flag_count resolved_flag_count unresolved_flag_count
|
||||
child_count deleted_child_count active_child_count
|
||||
pool_count deleted_pool_count active_pool_count series_pool_count collection_pool_count
|
||||
appeal_count approval_count replacement_count
|
||||
]
|
||||
|
||||
# allow e.g. `deleted_comments` as a synonym for `deleted_comment_count`
|
||||
COUNT_METATAG_SYNONYMS = COUNT_METATAGS.map { |str| str.delete_suffix("_count").pluralize }
|
||||
|
||||
METATAGS = %w[
|
||||
-user user -approver approver commenter comm noter noteupdater artcomm
|
||||
-pool pool ordpool -favgroup favgroup -fav fav ordfav md5 -rating rating
|
||||
@@ -7,10 +19,32 @@ class Tag < ApplicationRecord
|
||||
-source id -id date age order limit -status status tagcount parent -parent
|
||||
child pixiv_id pixiv search upvote downvote filetype -filetype flagger
|
||||
-flagger appealer -appealer disapproval -disapproval
|
||||
] + TagCategory.short_name_list.map {|x| "#{x}tags"}
|
||||
] + TagCategory.short_name_list.map {|x| "#{x}tags"} + COUNT_METATAGS + COUNT_METATAG_SYNONYMS
|
||||
|
||||
SUBQUERY_METATAGS = %w[commenter comm noter noteupdater artcomm flagger -flagger appealer -appealer]
|
||||
|
||||
ORDER_METATAGS = %w[
|
||||
id id_desc
|
||||
score score_asc
|
||||
favcount favcount_asc
|
||||
created_at created_at_asc
|
||||
change change_asc
|
||||
comment comment_asc
|
||||
comment_bumped comment_bumped_asc
|
||||
note note_asc
|
||||
artcomm artcomm_asc
|
||||
mpixels mpixels_asc
|
||||
portrait landscape
|
||||
filesize filesize_asc
|
||||
tagcount tagcount_asc
|
||||
rank
|
||||
random
|
||||
custom
|
||||
] +
|
||||
COUNT_METATAGS +
|
||||
COUNT_METATAG_SYNONYMS.flat_map { |str| [str, "#{str}_asc"] } +
|
||||
TagCategory.short_name_list.flat_map { |str| ["#{str}tags", "#{str}tags_asc"] }
|
||||
|
||||
has_one :wiki_page, :foreign_key => "title", :primary_key => "name"
|
||||
has_one :artist, :foreign_key => "name", :primary_key => "name"
|
||||
has_one :antecedent_alias, -> {active}, :class_name => "TagAlias", :foreign_key => "antecedent_name", :primary_key => "name"
|
||||
@@ -757,7 +791,14 @@ class Tag < ApplicationRecord
|
||||
q[:child] = g2.downcase
|
||||
|
||||
when "order"
|
||||
q[:order] = g2.downcase
|
||||
g2 = g2.downcase
|
||||
|
||||
order, suffix, _ = g2.partition(/_(asc|desc)\z/i)
|
||||
if order.in?(COUNT_METATAG_SYNONYMS)
|
||||
g2 = order.singularize + "_count" + suffix
|
||||
end
|
||||
|
||||
q[:order] = g2
|
||||
|
||||
when "limit"
|
||||
# Do nothing. The controller takes care of it.
|
||||
@@ -791,6 +832,13 @@ class Tag < ApplicationRecord
|
||||
q[:downvote] = User.name_to_id(g2)
|
||||
end
|
||||
|
||||
when *COUNT_METATAGS
|
||||
q[g1.to_sym] = parse_helper(g2)
|
||||
|
||||
when *COUNT_METATAG_SYNONYMS
|
||||
g1 = "#{g1.singularize}_count"
|
||||
q[g1.to_sym] = parse_helper(g2)
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
@@ -175,7 +175,7 @@ class Upload < ApplicationRecord
|
||||
end
|
||||
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post)).reorder("")
|
||||
where(post_id: PostQueryBuilder.new(query).build.reorder(""))
|
||||
end
|
||||
|
||||
def search(params)
|
||||
|
||||
Reference in New Issue
Block a user