pools: allow searching pools by post id or post count.
All pools containing post #1: https://danbooru.donmai.us/pools?search[post_ids_include]=1 All pools containing either post #1 or #2: https://danbooru.donmai.us/pools?search[post_ids_include]=1,2 https://danbooru.donmai.us/pools?search[post_ids_include]=1+2 Pools with 1-100 posts: https://danbooru.donmai.us/pools?search[post_id_count]=1..100 Pools with no posts (empty pools): https://danbooru.donmai.us/pools?search[post_id_count]=0
This commit is contained in:
@@ -35,6 +35,18 @@ class ApplicationRecord < ActiveRecord::Base
|
|||||||
where.not("#{qualified_column_for(attr)} ~ ?", "(?e)" + value)
|
where.not("#{qualified_column_for(attr)} ~ ?", "(?e)" + value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def where_array_includes(attr, values)
|
||||||
|
where("#{qualified_column_for(attr)} && ARRAY[?]", values)
|
||||||
|
end
|
||||||
|
|
||||||
|
def where_array_count(attr, value)
|
||||||
|
relation = all
|
||||||
|
qualified_column = "cardinality(#{qualified_column_for(attr)})"
|
||||||
|
parsed_range = Tag.parse_helper(value, :integer)
|
||||||
|
|
||||||
|
PostQueryBuilder.new(nil).add_range_relation(parsed_range, qualified_column, relation)
|
||||||
|
end
|
||||||
|
|
||||||
def search_boolean_attribute(attribute, params)
|
def search_boolean_attribute(attribute, params)
|
||||||
return all unless params[attribute]
|
return all unless params[attribute]
|
||||||
|
|
||||||
@@ -81,7 +93,8 @@ class ApplicationRecord < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def search_attribute(name, params)
|
def search_attribute(name, params)
|
||||||
type = type_for_attribute(name).type || reflect_on_association(name)&.class_name
|
column = column_for_attribute(name)
|
||||||
|
type = column.type || reflect_on_association(name)&.class_name
|
||||||
|
|
||||||
case type
|
case type
|
||||||
when "User"
|
when "User"
|
||||||
@@ -93,7 +106,11 @@ class ApplicationRecord < ActiveRecord::Base
|
|||||||
when :boolean
|
when :boolean
|
||||||
search_boolean_attribute(name, params)
|
search_boolean_attribute(name, params)
|
||||||
when :integer, :datetime
|
when :integer, :datetime
|
||||||
numeric_attribute_matches(name, params[name])
|
if column.array?
|
||||||
|
search_array_attribute(name, type, params)
|
||||||
|
else
|
||||||
|
numeric_attribute_matches(name, params[name])
|
||||||
|
end
|
||||||
else
|
else
|
||||||
raise NotImplementedError, "unhandled attribute type"
|
raise NotImplementedError, "unhandled attribute type"
|
||||||
end
|
end
|
||||||
@@ -149,6 +166,21 @@ class ApplicationRecord < ActiveRecord::Base
|
|||||||
relation
|
relation
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def search_array_attribute(name, type, params)
|
||||||
|
relation = all
|
||||||
|
|
||||||
|
if params[:"#{name}_include"] && type == :integer
|
||||||
|
items = params[:"#{name}_include"].to_s.scan(/\d+/).map(&:to_i)
|
||||||
|
relation = relation.where_array_includes(name, items)
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:"#{name.to_s.singularize}_count"]
|
||||||
|
relation = relation.where_array_count(name, params[:"#{name.to_s.singularize}_count"])
|
||||||
|
end
|
||||||
|
|
||||||
|
relation
|
||||||
|
end
|
||||||
|
|
||||||
def apply_default_order(params)
|
def apply_default_order(params)
|
||||||
if params[:order] == "custom"
|
if params[:order] == "custom"
|
||||||
parse_ids = Tag.parse_helper(params[:id])
|
parse_ids = Tag.parse_helper(params[:id])
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class Pool < ApplicationRecord
|
|||||||
def search(params)
|
def search(params)
|
||||||
q = super
|
q = super
|
||||||
|
|
||||||
q = q.search_attributes(params, :creator, :is_active, :is_deleted, :name, :description)
|
q = q.search_attributes(params, :creator, :is_active, :is_deleted, :name, :description, :post_ids)
|
||||||
q = q.text_attribute_matches(:description, params[:description_matches])
|
q = q.text_attribute_matches(:description, params[:description_matches])
|
||||||
|
|
||||||
if params[:name_matches].present?
|
if params[:name_matches].present?
|
||||||
|
|||||||
@@ -59,6 +59,25 @@ class PoolTest < ActiveSupport::TestCase
|
|||||||
assert_equal(@pool.id, Pool.find_by_name("test pool").id)
|
assert_equal(@pool.id, Pool.find_by_name("test pool").id)
|
||||||
assert_equal(@pool.id, Pool.search(name_matches: "test pool").first.id)
|
assert_equal(@pool.id, Pool.search(name_matches: "test pool").first.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "find pools by post id" do
|
||||||
|
@pool1 = create(:pool, name: "pool1")
|
||||||
|
@pool2 = create(:pool, name: "pool2")
|
||||||
|
@post1 = create(:post, tag_string: "pool:pool1")
|
||||||
|
@post2 = create(:post, tag_string: "pool:pool2")
|
||||||
|
|
||||||
|
assert_equal([@pool1.id], Pool.search(post_ids_include: @post1.id).pluck(:id))
|
||||||
|
assert_equal([@pool2.id, @pool1.id], Pool.search(post_ids_include: "#{@post1.id} #{@post2.id}").pluck(:id))
|
||||||
|
end
|
||||||
|
|
||||||
|
should "find pools by post id count" do
|
||||||
|
@pool1 = create(:pool, name: "pool1")
|
||||||
|
@pool2 = create(:pool, name: "pool2")
|
||||||
|
@post1 = create(:post, tag_string: "pool:pool1")
|
||||||
|
@post2 = create(:post, tag_string: "pool:pool1")
|
||||||
|
|
||||||
|
assert_equal([@pool1.id], Pool.search(post_id_count: 2).pluck(:id))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "Creating a pool" do
|
context "Creating a pool" do
|
||||||
|
|||||||
Reference in New Issue
Block a user