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)
|
||||
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)
|
||||
return all unless params[attribute]
|
||||
|
||||
@@ -81,7 +93,8 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
end
|
||||
|
||||
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
|
||||
when "User"
|
||||
@@ -93,7 +106,11 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
when :boolean
|
||||
search_boolean_attribute(name, params)
|
||||
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
|
||||
raise NotImplementedError, "unhandled attribute type"
|
||||
end
|
||||
@@ -149,6 +166,21 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
relation
|
||||
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)
|
||||
if params[:order] == "custom"
|
||||
parse_ids = Tag.parse_helper(params[:id])
|
||||
|
||||
@@ -57,7 +57,7 @@ class Pool < ApplicationRecord
|
||||
def search(params)
|
||||
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])
|
||||
|
||||
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.search(name_matches: "test pool").first.id)
|
||||
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
|
||||
|
||||
context "Creating a pool" do
|
||||
|
||||
Reference in New Issue
Block a user