Fix #3696: API: handle boolean params consistently
* Use ApplicationRecord#attribute_matches to handle boolean attributes consistently in search methods. * Add support for searching various boolean attributes that previously weren't supported.
This commit is contained in:
@@ -5,10 +5,34 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
|
||||
concerning :SearchMethods do
|
||||
class_methods do
|
||||
# range: "5", ">5", "<5", ">=5", "<=5", "5..10", "5,6,7"
|
||||
def attribute_matches(attribute, range)
|
||||
return all if range.blank?
|
||||
def attribute_matches(attribute, value)
|
||||
return all if value.nil?
|
||||
|
||||
column = column_for_attribute(attribute)
|
||||
case column.sql_type_metadata.type
|
||||
when :boolean
|
||||
boolean_attribute_matches(attribute, value)
|
||||
when :integer, :datetime
|
||||
numeric_attribute_matches(attribute, value)
|
||||
else
|
||||
raise ArgumentError, "unhandled attribute type"
|
||||
end
|
||||
end
|
||||
|
||||
def boolean_attribute_matches(attribute, value)
|
||||
if value.to_s.truthy?
|
||||
value = true
|
||||
elsif value.to_s.falsy?
|
||||
value = false
|
||||
else
|
||||
raise ArgumentError, "value must be truthy or falsy"
|
||||
end
|
||||
|
||||
where(attribute => value)
|
||||
end
|
||||
|
||||
# range: "5", ">5", "<5", ">=5", "<=5", "5..10", "5,6,7"
|
||||
def numeric_attribute_matches(attribute, range)
|
||||
column = column_for_attribute(attribute)
|
||||
qualified_column = "#{table_name}.#{column.name}"
|
||||
parsed_range = Tag.parse_helper(range, column.type)
|
||||
|
||||
@@ -566,17 +566,8 @@ class Artist < ApplicationRecord
|
||||
q = q.url_matches(params[:url_matches])
|
||||
end
|
||||
|
||||
if params[:is_active] == "true"
|
||||
q = q.active
|
||||
elsif params[:is_active] == "false"
|
||||
q = q.deleted
|
||||
end
|
||||
|
||||
if params[:is_banned] == "true"
|
||||
q = q.banned
|
||||
elsif params[:is_banned] == "false"
|
||||
q = q.unbanned
|
||||
end
|
||||
q = q.attribute_matches(:is_active, params[:is_active])
|
||||
q = q.attribute_matches(:is_banned, params[:is_banned])
|
||||
|
||||
if params[:creator_name].present?
|
||||
q = q.where("artists.creator_id = (select _.id from users _ where lower(_.name) = ?)", params[:creator_name].tr(" ", "_").mb_chars.downcase)
|
||||
|
||||
@@ -31,17 +31,8 @@ class ArtistVersion < ApplicationRecord
|
||||
q = q.where(artist_id: params[:artist_id].split(",").map(&:to_i))
|
||||
end
|
||||
|
||||
if params[:is_active] == "true"
|
||||
q = q.where("is_active = true")
|
||||
elsif params[:is_active] == "false"
|
||||
q = q.where("is_active = false")
|
||||
end
|
||||
|
||||
if params[:is_banned] == "true"
|
||||
q = q.where("is_banned = true")
|
||||
elsif params[:is_banned] == "false"
|
||||
q = q.where("is_banned = false")
|
||||
end
|
||||
q = q.attribute_matches(:is_active, params[:is_active])
|
||||
q = q.attribute_matches(:is_banned, params[:is_banned])
|
||||
|
||||
params[:order] ||= params.delete(:sort)
|
||||
if params[:order] == "name"
|
||||
|
||||
@@ -59,22 +59,6 @@ class Comment < ApplicationRecord
|
||||
where("comments.is_deleted = false")
|
||||
end
|
||||
|
||||
def sticky
|
||||
where("comments.is_sticky = true")
|
||||
end
|
||||
|
||||
def unsticky
|
||||
where("comments.is_sticky = false")
|
||||
end
|
||||
|
||||
def bumping
|
||||
where("comments.do_not_bump_post = false")
|
||||
end
|
||||
|
||||
def nonbumping
|
||||
where("comments.do_not_bump_post = true")
|
||||
end
|
||||
|
||||
def post_tags_match(query)
|
||||
PostQueryBuilder.new(query).build(self.joins(:post)).reorder("")
|
||||
end
|
||||
@@ -110,14 +94,9 @@ class Comment < ApplicationRecord
|
||||
q = q.for_creator(params[:creator_id].to_i)
|
||||
end
|
||||
|
||||
q = q.deleted if params[:is_deleted] == "true"
|
||||
q = q.undeleted if params[:is_deleted] == "false"
|
||||
|
||||
q = q.sticky if params[:is_sticky] == "true"
|
||||
q = q.unsticky if params[:is_sticky] == "false"
|
||||
|
||||
q = q.nonbumping if params[:do_not_bump_post] == "true"
|
||||
q = q.bumping if params[:do_not_bump_post] == "false"
|
||||
q = q.attribute_matches(:is_deleted, params[:is_deleted])
|
||||
q = q.attribute_matches(:is_sticky, params[:is_sticky])
|
||||
q = q.attribute_matches(:do_not_bump_post, params[:do_not_bump_post])
|
||||
|
||||
case params[:order]
|
||||
when "post_id", "post_id_desc"
|
||||
|
||||
@@ -218,11 +218,10 @@ class Dmail < ApplicationRecord
|
||||
q = q.where("from_id = ?", params[:from_id].to_i)
|
||||
end
|
||||
|
||||
if params[:is_spam].present?
|
||||
q = q.where("is_spam = ?", true)
|
||||
else
|
||||
q = q.where("is_spam = ?", false)
|
||||
end
|
||||
params[:is_spam] = false unless params[:is_spam].present?
|
||||
q = q.attribute_matches(:is_spam, params[:is_spam])
|
||||
q = q.attribute_matches(:is_read, params[:is_read])
|
||||
q = q.attribute_matches(:is_deleted, params[:is_deleted])
|
||||
|
||||
q = q.read if params[:read].to_s.truthy?
|
||||
q = q.unread if params[:read].to_s.falsy?
|
||||
|
||||
@@ -65,6 +65,8 @@ class FavoriteGroup < ApplicationRecord
|
||||
q = q.name_matches(params[:name_matches])
|
||||
end
|
||||
|
||||
q = q.attribute_matches(:is_public, params[:is_public])
|
||||
|
||||
q.apply_default_order(params)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -92,6 +92,8 @@ class ForumPost < ApplicationRecord
|
||||
q = q.joins(:topic).where("forum_topics.category_id = ?", params[:topic_category_id].to_i)
|
||||
end
|
||||
|
||||
q = q.attribute_matches(:is_deleted, params[:is_deleted])
|
||||
|
||||
q.apply_default_order(params)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -95,6 +95,10 @@ class ForumTopic < ApplicationRecord
|
||||
q = q.where("title = ?", params[:title])
|
||||
end
|
||||
|
||||
q = q.attribute_matches(:is_sticky, params[:is_sticky])
|
||||
q = q.attribute_matches(:is_locked, params[:is_locked])
|
||||
q = q.attribute_matches(:is_deleted, params[:is_deleted])
|
||||
|
||||
case params[:order]
|
||||
when "sticky"
|
||||
q = q.sticky_first
|
||||
|
||||
@@ -47,11 +47,7 @@ class Note < ApplicationRecord
|
||||
q = q.body_matches(params[:body_matches])
|
||||
end
|
||||
|
||||
if params[:is_active] == "true"
|
||||
q = q.active
|
||||
elsif params[:is_active] == "false"
|
||||
q = q.where("is_active = false")
|
||||
end
|
||||
q = q.attribute_matches(:is_active, params[:is_active])
|
||||
|
||||
if params[:post_id].present?
|
||||
q = q.where(post_id: params[:post_id].split(",").map(&:to_i))
|
||||
|
||||
@@ -17,6 +17,8 @@ class NoteVersion < ApplicationRecord
|
||||
q = q.where(note_id: params[:note_id].split(",").map(&:to_i))
|
||||
end
|
||||
|
||||
q = q.attribute_matches(:is_active, params[:is_active])
|
||||
|
||||
q.apply_default_order(params)
|
||||
end
|
||||
|
||||
|
||||
@@ -70,23 +70,14 @@ class Pool < ApplicationRecord
|
||||
q = q.where(creator_id: params[:creator_id].split(",").map(&:to_i))
|
||||
end
|
||||
|
||||
if params[:is_active] == "true"
|
||||
q = q.where("pools.is_active = true")
|
||||
elsif params[:is_active] == "false"
|
||||
q = q.where("pools.is_active = false")
|
||||
end
|
||||
|
||||
if params[:category] == "series"
|
||||
q = q.series
|
||||
elsif params[:category] == "collection"
|
||||
q = q.collection
|
||||
end
|
||||
|
||||
if params[:is_deleted] == "true"
|
||||
q = q.deleted
|
||||
else
|
||||
q = q.undeleted
|
||||
end
|
||||
q = q.attribute_matches(:is_active, params[:is_active])
|
||||
q = q.attribute_matches(:is_deleted, params[:is_deleted])
|
||||
|
||||
params[:order] ||= params.delete(:sort)
|
||||
case params[:order]
|
||||
|
||||
@@ -98,11 +98,7 @@ class PostFlag < ApplicationRecord
|
||||
q = q.post_tags_match(params[:post_tags_match])
|
||||
end
|
||||
|
||||
if params[:is_resolved] == "true"
|
||||
q = q.resolved
|
||||
elsif params[:is_resolved] == "false"
|
||||
q = q.unresolved
|
||||
end
|
||||
q = q.attribute_matches(:is_resolved, params[:is_resolved])
|
||||
|
||||
case params[:category]
|
||||
when "normal"
|
||||
|
||||
@@ -903,6 +903,8 @@ class Tag < ApplicationRecord
|
||||
q = q.joins("LEFT JOIN artists ON tags.name = artists.name").where("artists.name IS NULL OR artists.is_active = false")
|
||||
end
|
||||
|
||||
q = q.attribute_matches(:is_locked, params[:is_locked])
|
||||
|
||||
params[:order] ||= params.delete(:sort)
|
||||
case params[:order]
|
||||
when "name"
|
||||
|
||||
@@ -92,6 +92,9 @@ class WikiPage < ApplicationRecord
|
||||
q = q.where("other_names is null or other_names = ''")
|
||||
end
|
||||
|
||||
q = q.attribute_matches(:is_locked, params[:is_locked])
|
||||
q = q.attribute_matches(:is_deleted, params[:is_deleted])
|
||||
|
||||
params[:order] ||= params.delete(:sort)
|
||||
case params[:order]
|
||||
when "title"
|
||||
|
||||
@@ -20,6 +20,9 @@ class WikiPageVersion < ApplicationRecord
|
||||
q = q.where("wiki_page_id = ?", params[:wiki_page_id].to_i)
|
||||
end
|
||||
|
||||
q = q.attribute_matches(:is_locked, params[:is_locked])
|
||||
q = q.attribute_matches(:is_deleted, params[:is_deleted])
|
||||
|
||||
q.apply_default_order(params)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user