post versions: add ability to search post versions by tags.

* Add ability to search /post_versions by added tags, removed tags, or
  changed tags (added or removed).

* Add 'History' link to the sidebar of the /posts index. This is a
  shortcut for a /post_versions search of the current tag.
This commit is contained in:
evazion
2019-09-26 20:28:30 -05:00
parent 12de26d2cf
commit 2b4ee0ee8f
7 changed files with 56 additions and 16 deletions

View File

@@ -39,10 +39,14 @@ class ApplicationRecord < ActiveRecord::Base
where.not("#{qualified_column_for(attr)} ~ ?", "(?e)" + value)
end
def where_array_includes(attr, values)
def where_array_includes_any(attr, values)
where("#{qualified_column_for(attr)} && ARRAY[?]", values)
end
def where_array_includes_all(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)})"
@@ -100,6 +104,10 @@ class ApplicationRecord < ActiveRecord::Base
column = column_for_attribute(name)
type = column.type || reflect_on_association(name)&.class_name
if column.array?
return search_array_attribute(name, type, params)
end
case type
when "User"
search_user_attribute(name, params)
@@ -110,11 +118,7 @@ class ApplicationRecord < ActiveRecord::Base
when :boolean
search_boolean_attribute(name, params)
when :integer, :datetime
if column.array?
search_array_attribute(name, type, params)
else
numeric_attribute_matches(name, params[name])
end
numeric_attribute_matches(name, params[name])
else
raise NotImplementedError, "unhandled attribute type"
end
@@ -173,9 +177,16 @@ class ApplicationRecord < ActiveRecord::Base
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)
if params[:"#{name}_include_any"]
items = params[:"#{name}_include_any"].to_s.scan(/[^[:space:]]+/)
items = items.map(&:to_i) if type == :integer
relation = relation.where_array_includes_any(name, items)
elsif params[:"#{name}_include_all"]
items = params[:"#{name}_include_any"].to_s.scan(/[^[:space:]]+/)
items = items.map(&:to_i) if type == :integer
relation = relation.where_array_includes_all(name, items)
end
if params[:"#{name.to_s.singularize}_count"]

View File

@@ -19,7 +19,7 @@ class PoolArchive < ApplicationRecord
end
def for_post_id(post_id)
where_array_includes(:added_post_ids, [post_id]).or(where_array_includes(:removed_post_ids, [post_id]))
where_array_includes_any(:added_post_ids, [post_id]).or(where_array_includes_any(:removed_post_ids, [post_id]))
end
def search(params)

View File

@@ -18,9 +18,23 @@ class PostArchive < ApplicationRecord
end
module SearchMethods
def changed_tags_include(tag)
where_array_includes_all(:added_tags, [tag]).or(where_array_includes_all(:removed_tags, [tag]))
end
def changed_tags_include_all(tags)
tags.reduce(all) do |relation, tag|
relation.changed_tags_include(tag)
end
end
def search(params)
q = super
q = q.search_attributes(params, :updater_id, :post_id, :rating, :rating_changed, :parent_id, :parent_changed, :source, :source_changed, :version)
q = q.search_attributes(params, :updater_id, :post_id, :tags, :added_tags, :removed_tags, :rating, :rating_changed, :parent_id, :parent_changed, :source, :source_changed, :version)
if params[:changed_tags]
q = q.changed_tags_include_all(params[:changed_tags].scan(/[^[:space:]]+/))
end
if params[:updater_name].present?
q = q.where(updater_id: User.name_to_id(params[:updater_name]))