search: clean up saved search: metatag.
* Fix not being able to negate the search: metatag. * Fix not being able to use the search: metatag twice in the same search.
This commit is contained in:
@@ -38,6 +38,7 @@ class PostQueryBuilder
|
||||
-filetype filetype
|
||||
-disapproved disapproved
|
||||
-parent parent
|
||||
-search search
|
||||
md5
|
||||
width
|
||||
height
|
||||
@@ -53,7 +54,6 @@ class PostQueryBuilder
|
||||
tagcount
|
||||
child
|
||||
pixiv_id pixiv
|
||||
search
|
||||
embedded
|
||||
] + TagCategory.short_name_list.map {|x| "#{x}tags"} + COUNT_METATAGS + COUNT_METATAG_SYNONYMS
|
||||
|
||||
@@ -156,19 +156,13 @@ class PostQueryBuilder
|
||||
relation
|
||||
end
|
||||
|
||||
def add_saved_search_relation(saved_searches, relation)
|
||||
saved_searches.each do |saved_search|
|
||||
if saved_search == "all"
|
||||
post_ids = SavedSearch.post_ids_for(CurrentUser.id)
|
||||
else
|
||||
post_ids = SavedSearch.post_ids_for(CurrentUser.id, label: saved_search)
|
||||
end
|
||||
|
||||
post_ids = [0] if post_ids.empty?
|
||||
relation = relation.where("posts.id": post_ids)
|
||||
def saved_search_matches(label)
|
||||
case label.downcase
|
||||
when "all"
|
||||
Post.where(id: SavedSearch.post_ids_for(CurrentUser.id))
|
||||
else
|
||||
Post.where(id: SavedSearch.post_ids_for(CurrentUser.id, label: label))
|
||||
end
|
||||
|
||||
relation
|
||||
end
|
||||
|
||||
def status_matches(status)
|
||||
@@ -348,8 +342,12 @@ class PostQueryBuilder
|
||||
relation = relation.merge(commentary_matches(query))
|
||||
end
|
||||
|
||||
if q[:saved_searches]
|
||||
relation = add_saved_search_relation(q[:saved_searches], relation)
|
||||
q[:saved_searches_neg].to_a.each do |query|
|
||||
relation = relation.merge(saved_search_matches(query).negate)
|
||||
end
|
||||
|
||||
q[:saved_searches].to_a.each do |query|
|
||||
relation = relation.merge(saved_search_matches(query))
|
||||
end
|
||||
|
||||
q[:user_neg].to_a.each do |username|
|
||||
@@ -886,6 +884,10 @@ class PostQueryBuilder
|
||||
q[:commentary] ||= []
|
||||
q[:commentary] << g2
|
||||
|
||||
when "-search"
|
||||
q[:saved_searches_neg] ||= []
|
||||
q[:saved_searches_neg] << g2
|
||||
|
||||
when "search"
|
||||
q[:saved_searches] ||= []
|
||||
q[:saved_searches] << g2
|
||||
|
||||
@@ -14,7 +14,6 @@ class SavedSearch < ApplicationRecord
|
||||
memoize :redis
|
||||
|
||||
def post_ids_for(user_id, label: nil)
|
||||
label = normalize_label(label) if label
|
||||
queries = queries_for(user_id, label: label)
|
||||
post_ids = Set.new
|
||||
queries.each do |query|
|
||||
@@ -135,13 +134,10 @@ class SavedSearch < ApplicationRecord
|
||||
concerning :Queries do
|
||||
class_methods do
|
||||
def queries_for(user_id, label: nil, options: {})
|
||||
SavedSearch
|
||||
.where(user_id: user_id)
|
||||
.labeled(label)
|
||||
.pluck(:query)
|
||||
.map {|x| PostQueryBuilder.normalize_query(x, sort: true)}
|
||||
.sort
|
||||
.uniq
|
||||
searches = SavedSearch.where(user_id: user_id)
|
||||
searches = searches.labeled(label) if label.present?
|
||||
queries = searches.pluck(:query).map { |query| PostQueryBuilder.normalize_query(query, sort: true) }
|
||||
queries.sort.uniq
|
||||
end
|
||||
end
|
||||
|
||||
@@ -160,7 +156,7 @@ class SavedSearch < ApplicationRecord
|
||||
validate :validate_count
|
||||
before_validation :normalize_query
|
||||
before_validation :normalize_labels
|
||||
scope :labeled, ->(label) { label.present? ? where("labels @> string_to_array(?, '~~~~')", label) : where("true") }
|
||||
scope :labeled, ->(label) { where_array_includes_any_lower(:labels, [normalize_label(label)]) }
|
||||
|
||||
def validate_count
|
||||
if user.saved_searches.count + 1 > user.max_saved_searches
|
||||
|
||||
@@ -597,34 +597,28 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
|
||||
assert_tag_match([post], "pixiv_id:none")
|
||||
end
|
||||
|
||||
context "saved searches" do
|
||||
setup do
|
||||
@post1 = create(:post, tag_string: "aaa")
|
||||
@post2 = create(:post, tag_string: "bbb")
|
||||
create(:saved_search, query: "aaa", labels: ["zzz"], user: CurrentUser.user)
|
||||
create(:saved_search, query: "bbb", user: CurrentUser.user)
|
||||
end
|
||||
should "return posts for the search: metatag" do
|
||||
@post1 = create(:post, tag_string: "aaa")
|
||||
@post2 = create(:post, tag_string: "bbb")
|
||||
create(:saved_search, query: "aaa", labels: ["zzz"], user: CurrentUser.user)
|
||||
create(:saved_search, query: "bbb", user: CurrentUser.user)
|
||||
|
||||
context "labeled" do
|
||||
should "work" do
|
||||
SavedSearch.expects(:post_ids_for).with(CurrentUser.id, label: "zzz").returns([@post1.id])
|
||||
assert_tag_match([@post1], "search:zzz")
|
||||
end
|
||||
end
|
||||
Redis.any_instance.stubs(:exists).with("search:aaa").returns(true)
|
||||
Redis.any_instance.stubs(:exists).with("search:bbb").returns(true)
|
||||
Redis.any_instance.stubs(:smembers).with("search:aaa").returns([@post1.id])
|
||||
Redis.any_instance.stubs(:smembers).with("search:bbb").returns([@post2.id])
|
||||
|
||||
context "missing" do
|
||||
should "work" do
|
||||
SavedSearch.expects(:post_ids_for).with(CurrentUser.id, label: "uncategorized").returns([@post2.id])
|
||||
assert_tag_match([@post2], "search:uncategorized")
|
||||
end
|
||||
end
|
||||
assert_tag_match([@post1], "search:zzz")
|
||||
assert_tag_match([@post1], "search:ZZZ")
|
||||
assert_tag_match([@post2, @post1], "search:all")
|
||||
assert_tag_match([@post2, @post1], "search:ALL")
|
||||
assert_tag_match([], "search:does_not_exist")
|
||||
|
||||
context "all" do
|
||||
should "work" do
|
||||
SavedSearch.expects(:post_ids_for).with(CurrentUser.id).returns([@post1.id, @post2.id])
|
||||
assert_tag_match([@post2, @post1], "search:all")
|
||||
end
|
||||
end
|
||||
assert_tag_match([@post2], "-search:zzz")
|
||||
assert_tag_match([@post2], "-search:ZZZ")
|
||||
assert_tag_match([], "-search:all")
|
||||
assert_tag_match([], "-search:ALL")
|
||||
assert_tag_match([@post2, @post1], "-search:does_not_exist")
|
||||
end
|
||||
|
||||
should "return posts for a rating:<s|q|e> metatag" do
|
||||
|
||||
Reference in New Issue
Block a user