search: fix bug with negated user metatags.
Bug: searching for "filetype:jpg -user:evazion" would negate the filetype:jpg metatag too. This was because the -user:<name> metatag was negating the entire cumulative relation instead of just the user:<name> clause.
This commit is contained in:
@@ -123,30 +123,39 @@ class PostQueryBuilder
|
|||||||
array.map(&:to_escaped_for_tsquery)
|
array.map(&:to_escaped_for_tsquery)
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_user_relation(field, username, relation)
|
def user_matches(field, username)
|
||||||
if username == "any"
|
if username == "any"
|
||||||
relation.where.not(field => nil)
|
Post.where.not(field => nil)
|
||||||
elsif username == "none"
|
elsif username == "none"
|
||||||
relation.where(field => nil)
|
Post.where(field => nil)
|
||||||
else
|
else
|
||||||
relation.where(field => User.name_matches(username))
|
Post.where(field => User.name_matches(username))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_user_subquery_relation(table, username, relation, field: :creator, &block)
|
def user_subquery_matches(subquery, username, field: :creator, &block)
|
||||||
subquery = table.where("post_id = posts.id").select(1)
|
subquery = subquery.where("post_id = posts.id").select(1)
|
||||||
|
|
||||||
if username == "any"
|
if username == "any"
|
||||||
relation.where("EXISTS (#{subquery.to_sql})")
|
Post.where("EXISTS (#{subquery.to_sql})")
|
||||||
elsif username == "none"
|
elsif username == "none"
|
||||||
relation.where("NOT EXISTS (#{subquery.to_sql})")
|
Post.where("NOT EXISTS (#{subquery.to_sql})")
|
||||||
elsif block.nil?
|
elsif block.nil?
|
||||||
subquery = subquery.where(field => User.name_matches(username))
|
subquery = subquery.where(field => User.name_matches(username))
|
||||||
relation.where("EXISTS (#{subquery.to_sql})")
|
Post.where("EXISTS (#{subquery.to_sql})")
|
||||||
else
|
else
|
||||||
subquery = subquery.merge(block.call(username))
|
subquery = subquery.merge(block.call(username))
|
||||||
return relation.none if subquery.to_sql.blank?
|
return Post.none if subquery.to_sql.blank?
|
||||||
relation.where("EXISTS (#{subquery.to_sql})")
|
Post.where("EXISTS (#{subquery.to_sql})")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def flagger_matches(username)
|
||||||
|
flags = PostFlag.unscoped.category_matches("normal")
|
||||||
|
|
||||||
|
user_subquery_matches(flags, username) do |username|
|
||||||
|
flagger = User.find_by_name(username)
|
||||||
|
PostFlag.unscoped.creator_matches(flagger, CurrentUser.user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -375,19 +384,19 @@ class PostQueryBuilder
|
|||||||
end
|
end
|
||||||
|
|
||||||
q[:user_neg].to_a.each do |username|
|
q[:user_neg].to_a.each do |username|
|
||||||
relation = add_user_relation(:uploader, username, relation).negate
|
relation = relation.merge(user_matches(:uploader, username).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:user].to_a.each do |username|
|
q[:user].to_a.each do |username|
|
||||||
relation = add_user_relation(:uploader, username, relation)
|
relation = relation.merge(user_matches(:uploader, username))
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:approver_neg].to_a.each do |username|
|
q[:approver_neg].to_a.each do |username|
|
||||||
relation = add_user_relation(:approver, username, relation).negate
|
relation = relation.merge(user_matches(:approver, username).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:approver].to_a.each do |username|
|
q[:approver].to_a.each do |username|
|
||||||
relation = add_user_relation(:approver, username, relation)
|
relation = relation.merge(user_matches(:approver, username))
|
||||||
end
|
end
|
||||||
|
|
||||||
if q[:disapproved]
|
if q[:disapproved]
|
||||||
@@ -414,58 +423,52 @@ class PostQueryBuilder
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:flagger_neg].to_a.each do |flagger|
|
q[:flagger_neg].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(PostFlag.unscoped.category_matches("normal"), flagger, relation) do |username|
|
relation = relation.merge(flagger_matches(username).negate)
|
||||||
flagger = User.find_by_name(username)
|
|
||||||
PostFlag.unscoped.creator_matches(flagger, CurrentUser.user)
|
|
||||||
end.negate
|
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:flagger].to_a.each do |flagger|
|
q[:flagger].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(PostFlag.unscoped.category_matches("normal"), flagger, relation) do |username|
|
relation = relation.merge(flagger_matches(username))
|
||||||
flagger = User.find_by_name(username)
|
|
||||||
PostFlag.unscoped.creator_matches(flagger, CurrentUser.user)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:appealer_neg].to_a.each do |appealer|
|
q[:appealer_neg].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(PostAppeal.unscoped, appealer, relation).negate
|
relation = relation.merge(user_subquery_matches(PostAppeal.unscoped, username).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:appealer].to_a.each do |appealer|
|
q[:appealer].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(PostAppeal.unscoped, appealer, relation)
|
relation = relation.merge(user_subquery_matches(PostAppeal.unscoped, username))
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:commenter_neg].to_a.each do |commenter|
|
q[:commenter_neg].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(Comment.unscoped, commenter, relation).negate
|
relation = relation.merge(user_subquery_matches(Comment.unscoped, username).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:commenter].to_a.each do |commenter|
|
q[:commenter].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(Comment.unscoped, commenter, relation)
|
relation = relation.merge(user_subquery_matches(Comment.unscoped, username))
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:noter_neg].to_a.each do |noter|
|
q[:noter_neg].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(NoteVersion.unscoped.where(version: 1), noter, relation, field: :updater).negate
|
relation = relation.merge(user_subquery_matches(NoteVersion.unscoped.where(version: 1), username, field: :updater).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:noter].to_a.each do |noter|
|
q[:noter].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(NoteVersion.unscoped.where(version: 1), noter, relation, field: :updater)
|
relation = relation.merge(user_subquery_matches(NoteVersion.unscoped.where(version: 1), username, field: :updater))
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:note_updater_neg].to_a.each do |note_updater|
|
q[:note_updater_neg].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(NoteVersion.unscoped, note_updater, relation, field: :updater).negate
|
relation = relation.merge(user_subquery_matches(NoteVersion.unscoped, username, field: :updater).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:note_updater].to_a.each do |note_updater|
|
q[:note_updater].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(NoteVersion.unscoped, note_updater, relation, field: :updater)
|
relation = relation.merge(user_subquery_matches(NoteVersion.unscoped, username, field: :updater))
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:commentary_updater_neg].to_a.each do |username|
|
q[:commentary_updater_neg].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(ArtistCommentaryVersion.unscoped, username, relation, field: :updater).negate
|
relation = relation.merge(user_subquery_matches(ArtistCommentaryVersion.unscoped, username, field: :updater).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:commentary_updater].to_a.each do |username|
|
q[:commentary_updater].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(ArtistCommentaryVersion.unscoped, username, relation, field: :updater)
|
relation = relation.merge(user_subquery_matches(ArtistCommentaryVersion.unscoped, username, field: :updater))
|
||||||
end
|
end
|
||||||
|
|
||||||
if q[:post_id_negated]
|
if q[:post_id_negated]
|
||||||
@@ -552,20 +555,20 @@ class PostQueryBuilder
|
|||||||
relation = relation.where(id: favgroup.select("unnest(post_ids)"))
|
relation = relation.where(id: favgroup.select("unnest(post_ids)"))
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:upvoter].to_a.each do |upvoter|
|
q[:upvoter].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(PostVote.positive.visible(CurrentUser.user), upvoter, relation, field: :user)
|
relation = relation.merge(user_subquery_matches(PostVote.positive.visible(CurrentUser.user), username, field: :user))
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:upvoter_neg].to_a.each do |upvoter|
|
q[:upvoter_neg].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(PostVote.positive.visible(CurrentUser.user), upvoter, relation, field: :user).negate
|
relation = relation.merge(user_subquery_matches(PostVote.positive.visible(CurrentUser.user), username, field: :user).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:downvoter].to_a.each do |downvoter|
|
q[:downvoter].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(PostVote.negative.visible(CurrentUser.user), downvoter, relation, field: :user)
|
relation = relation.merge(user_subquery_matches(PostVote.negative.visible(CurrentUser.user), username, field: :user))
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:downvoter_neg].to_a.each do |downvoter|
|
q[:downvoter_neg].to_a.each do |username|
|
||||||
relation = add_user_subquery_relation(PostVote.negative.visible(CurrentUser.user), downvoter, relation, field: :user).negate
|
relation = relation.merge(user_subquery_matches(PostVote.negative.visible(CurrentUser.user), username, field: :user).negate)
|
||||||
end
|
end
|
||||||
|
|
||||||
q[:fav_neg].to_a.each do |username|
|
q[:fav_neg].to_a.each do |username|
|
||||||
|
|||||||
@@ -2141,6 +2141,7 @@ class PostTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
assert_tag_match([posts[0]], "user:#{users[0].name}")
|
assert_tag_match([posts[0]], "user:#{users[0].name}")
|
||||||
assert_tag_match([posts[1]], "-user:#{users[0].name}")
|
assert_tag_match([posts[1]], "-user:#{users[0].name}")
|
||||||
|
assert_tag_match([posts[1]], "filetype:jpg -user:#{users[0].name}")
|
||||||
end
|
end
|
||||||
|
|
||||||
should "return posts for the approver:<name> metatag" do
|
should "return posts for the approver:<name> metatag" do
|
||||||
|
|||||||
Reference in New Issue
Block a user