Fix #4601: Hide deleted pools by default in pool search.
* On /pools, hide deleted pools by default in HTML responses. Don't filter out deleted pools in API responses. * API change: on /forum_topics, only hide deleted forum topics by default for HTML responses, not for API responses. Explicitly do https://danbooru.donmai.us/forum_topics.json?search[is_deleted]=false to filter out deleted topics. * API change: on /tags, only hide empty tags by default for HTML responses, not for API responses. Explicitly do https://danbooru.donmai.us/tags.json?search[is_empty]=false to filter out empty tags. * API change: on /pools, default to 20 posts per page for API responses, not 40. * API change: add `search[is_empty]` param to /tags.json endpoint. `search[hide_empty]=true` is deprecated in favor of `search[is_empty]=false`. * On /pools, add option to show/hide deleted pools in search form. * Fix the /forum_topics page putting `search[order]=sticky&limit=40` in the URL when browsing past page 1.
This commit is contained in:
@@ -15,11 +15,12 @@ class ForumTopicsController < ApplicationController
|
||||
end
|
||||
|
||||
def index
|
||||
params[:search] ||= {}
|
||||
params[:search][:order] ||= "sticky" if request.format.html?
|
||||
params[:limit] ||= 40
|
||||
|
||||
@forum_topics = authorize ForumTopic.visible(CurrentUser.user).paginated_search(params)
|
||||
if request.format.html?
|
||||
limit = params.fetch(:limit, 40)
|
||||
@forum_topics = authorize ForumTopic.visible(CurrentUser.user).paginated_search(params, limit: limit, defaults: { order: "sticky", is_deleted: false })
|
||||
else
|
||||
@forum_topics = authorize ForumTopic.visible(CurrentUser.user).paginated_search(params)
|
||||
end
|
||||
|
||||
if request.format.atom?
|
||||
@forum_topics = @forum_topics.includes(:creator, :original_post)
|
||||
|
||||
@@ -12,7 +12,11 @@ class PoolsController < ApplicationController
|
||||
end
|
||||
|
||||
def index
|
||||
@pools = authorize Pool.paginated_search(params, count_pages: true)
|
||||
if request.format.html?
|
||||
@pools = authorize Pool.paginated_search(params, count_pages: true, defaults: { is_deleted: false })
|
||||
else
|
||||
@pools = authorize Pool.paginated_search(params, count_pages: true)
|
||||
end
|
||||
|
||||
respond_with(@pools)
|
||||
end
|
||||
|
||||
@@ -7,7 +7,12 @@ class TagsController < ApplicationController
|
||||
end
|
||||
|
||||
def index
|
||||
@tags = authorize Tag.paginated_search(params, hide_empty: true)
|
||||
if request.format.html?
|
||||
@tags = authorize Tag.paginated_search(params, defaults: { hide_empty: true })
|
||||
else
|
||||
@tags = authorize Tag.paginated_search(params)
|
||||
end
|
||||
|
||||
@tags = @tags.includes(:consequent_aliases) if request.format.html?
|
||||
respond_with(@tags)
|
||||
end
|
||||
|
||||
@@ -14,12 +14,21 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
extending(PaginationExtension).paginate(*args, **options)
|
||||
end
|
||||
|
||||
def paginated_search(params, count_pages: params[:search].present?, **defaults)
|
||||
# Perform a search using the model's `search` method, then paginate the results.
|
||||
#
|
||||
# params [Hash] The URL request params from the user
|
||||
# page [Integer] The page number
|
||||
# limit [Integer] The number of posts per page
|
||||
# count_pages [Boolean] If true, show the exact number of pages of
|
||||
# results. If false (the default), don't count the exact number of pages
|
||||
# of results; assume there are too many pages to count.
|
||||
# defaults [Hash] The default params for the search
|
||||
def paginated_search(params, page: params[:page], limit: params[:limit], count_pages: params[:search].present?, defaults: {})
|
||||
search_params = params.fetch(:search, {}).permit!
|
||||
search_params = defaults.merge(search_params).with_indifferent_access
|
||||
|
||||
max_limit = (params[:format] == "sitemap") ? 10_000 : 1_000
|
||||
search(search_params).paginate(params[:page], limit: params[:limit], max_limit: max_limit, search_count: count_pages)
|
||||
search(search_params).paginate(page, limit: limit, max_limit: max_limit, search_count: count_pages)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -118,10 +118,6 @@ class ForumTopic < ApplicationRecord
|
||||
q = q.apply_default_order(params)
|
||||
end
|
||||
|
||||
unless params[:is_deleted].present?
|
||||
q = q.active
|
||||
end
|
||||
|
||||
q
|
||||
end
|
||||
end
|
||||
|
||||
@@ -287,6 +287,12 @@ class Tag < ApplicationRecord
|
||||
q = q.name_or_alias_matches(params[:name_or_alias_matches])
|
||||
end
|
||||
|
||||
if params[:is_empty].to_s.truthy?
|
||||
q = q.empty
|
||||
elsif params[:is_empty].to_s.falsy?
|
||||
q = q.nonempty
|
||||
end
|
||||
|
||||
if params[:hide_empty].to_s.truthy?
|
||||
q = q.nonempty
|
||||
end
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<%= f.input :name_matches, label: "Name", input_html: { value: params.dig(:search, :name_matches), "data-autocomplete": "pool" } %>
|
||||
<%= f.input :description_matches, label: "Description", input_html: { value: params.dig(:search, :description_matches) } %>
|
||||
<%= f.input :post_tags_match, label: "Post tags", input_html: { value: params.dig(:search, :post_tags_match), "data-autocomplete": "tag-query" } %>
|
||||
<%= f.input :is_deleted, label: "Deleted?", as: :select, include_blank: true, selected: params[:search][:is_deleted] %>
|
||||
<%= f.input :category, collection: %w[series collection], include_blank: true, selected: params[:search][:category] %>
|
||||
<%= f.input :order, collection: [%w[Last\ updated updated_at], %w[Name name], %w[Recently\ created created_at], %w[Post\ count post_count]], include_blank: true, selected: params.dig(:search, :order) %>
|
||||
<%= f.submit "Search" %>
|
||||
|
||||
@@ -36,10 +36,12 @@ class TagsControllerTest < ActionDispatch::IntegrationTest
|
||||
context "searching" do
|
||||
setup do
|
||||
as(@user) do
|
||||
@miku = create(:character_tag, name: "hatsune_miku")
|
||||
@miku = create(:character_tag, name: "miku")
|
||||
@hatsune_miku = create(:character_tag, name: "hatsune_miku")
|
||||
@wokada = create(:artist_tag, name: "wokada")
|
||||
@vocaloid = create(:copyright_tag, name: "vocaloid")
|
||||
@weapon = create(:tag, name: "weapon")
|
||||
@axe = create(:tag, name: "axe")
|
||||
@empty = create(:tag, name: "empty", post_count: 0)
|
||||
|
||||
create(:tag_alias, antecedent_name: "miku", consequent_name: "hatsune_miku")
|
||||
@@ -54,22 +56,24 @@ class TagsControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
should respond_to_search({}).with { [@weapon, @vocaloid, @wokada, @miku, @tag] }
|
||||
should respond_to_search(name_matches: "hatsune_miku").with { @miku }
|
||||
should respond_to_search(name_normalize: "HATSUNE_MIKU ").with { @miku }
|
||||
should respond_to_search(name_or_alias_matches: "miku").with { @miku }
|
||||
should respond_to_search(fuzzy_name_matches: "hatsune_mika", order: "similarity").with { @miku }
|
||||
should respond_to_search({}).with { [@empty, @axe, @weapon, @vocaloid, @wokada, @hatsune_miku, @miku, @tag] }
|
||||
should respond_to_search(name_matches: "hatsune_miku").with { @hatsune_miku }
|
||||
should respond_to_search(name_normalize: "HATSUNE_MIKU ").with { @hatsune_miku }
|
||||
should respond_to_search(name_or_alias_matches: "miku").with { [@hatsune_miku, @miku] }
|
||||
should respond_to_search(fuzzy_name_matches: "hatsune_mika", order: "similarity").with { @hatsune_miku }
|
||||
should respond_to_search(name: "empty", hide_empty: "true").with { [] }
|
||||
should respond_to_search(name: "empty", hide_empty: "false").with { [@empty] }
|
||||
should respond_to_search(name: "empty", is_empty: "true").with { [@empty] }
|
||||
should respond_to_search(name: "empty", is_empty: "false").with { [] }
|
||||
|
||||
context "using includes" do
|
||||
should respond_to_search(name: "wokada", has_artist: "true").with { @wokada }
|
||||
should respond_to_search(name: "hatsune_miku", has_artist: "false").with { @miku }
|
||||
should respond_to_search(name: "hatsune_miku", has_wiki_page: "true").with { @miku }
|
||||
should respond_to_search(name: "hatsune_miku", has_artist: "false").with { @hatsune_miku }
|
||||
should respond_to_search(name: "hatsune_miku", has_wiki_page: "true").with { @hatsune_miku }
|
||||
should respond_to_search(name: "vocaloid", has_wiki_page: "false").with { @vocaloid }
|
||||
should respond_to_search(consequent_aliases: {antecedent_name: "miku"}).with { @miku }
|
||||
should respond_to_search(consequent_aliases: {antecedent_name: "miku"}).with { @hatsune_miku }
|
||||
should respond_to_search(consequent_implications: {antecedent_name: "axe"}).with { @weapon }
|
||||
should respond_to_search(wiki_page: {body_matches: "*vocaloid*"}).with { @miku }
|
||||
should respond_to_search(wiki_page: {body_matches: "*vocaloid*"}).with { @hatsune_miku }
|
||||
should respond_to_search(artist: {is_banned: "false"}).with { @wokada }
|
||||
should respond_to_search(has_dtext_links: "true").with { @vocaloid }
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user