diff --git a/app/controllers/bubbles_controller.rb b/app/controllers/bubbles_controller.rb index 8aa6850d8..8409b53ca 100644 --- a/app/controllers/bubbles_controller.rb +++ b/app/controllers/bubbles_controller.rb @@ -34,7 +34,7 @@ class BubblesController < ApplicationController private def set_filter - @filter = Current.user.filters.build params.permit(*Filter::PERMITTED_PARAMS) + @filter = Current.user.filters.from_params params.permit(*Filter::PERMITTED_PARAMS) end def set_bubble diff --git a/app/controllers/filters_controller.rb b/app/controllers/filters_controller.rb index e39456b18..c0523fa0d 100644 --- a/app/controllers/filters_controller.rb +++ b/app/controllers/filters_controller.rb @@ -3,7 +3,7 @@ class FiltersController < ApplicationController def create @filter = Current.user.filters.remember filter_params - redirect_to bubbles_path(@filter.to_params) + redirect_to bubbles_path(@filter.as_params) end def destroy @@ -24,7 +24,7 @@ class FiltersController < ApplicationController if request.referer == root_url redirect_to root_path else - redirect_to bubbles_path(@filter.to_params) + redirect_to bubbles_path(@filter.as_params) end end end diff --git a/app/models/filter.rb b/app/models/filter.rb index 64fc6d183..73b03c9c4 100644 --- a/app/models/filter.rb +++ b/app/models/filter.rb @@ -5,26 +5,22 @@ class Filter < ApplicationRecord has_one :account, through: :creator class << self + def from_params(params) + find_by_params(params) || build(params) + end + def remember(attrs) create!(attrs) rescue ActiveRecord::RecordNotUnique - find_by!(params_digest: digest_params(attrs)).tap(&:touch) + find_by_params(attrs).tap(&:touch) end - - def digest_params(params) - Digest::MD5.hexdigest params.to_h.sort.to_json - end - end - - def empty? - as_params.blank? end def bubbles @bubbles ||= begin result = creator.accessible_bubbles.indexed_by(indexed_by) result = result.active unless indexed_by.popped? - result = result.unassigned if assignments.unassigned? + result = result.unassigned if assignment_status.unassigned? result = result.assigned_to(assignees.ids) if assignees.present? result = result.assigned_by(assigners.ids) if assigners.present? result = result.in_bucket(buckets.ids) if buckets.present? @@ -37,6 +33,10 @@ class Filter < ApplicationRecord end end + def empty? + self.class.normalize_params(as_params).blank? + end + def cacheable? buckets.exists? end diff --git a/app/models/filter/fields.rb b/app/models/filter/fields.rb index 93faed6c7..9c2c212b0 100644 --- a/app/models/filter/fields.rb +++ b/app/models/filter/fields.rb @@ -3,36 +3,39 @@ module Filter::Fields INDEXES = %w[ most_discussed most_boosted newest oldest popped ] + delegate :default_value?, to: :class + class_methods do - def default_fields + def default_values { indexed_by: "most_active" } end + + def default_value?(key, value) + default_values[key.to_sym].eql?(value) + end end included do - store_accessor :fields, :indexed_by, :assignments, :terms + store_accessor :fields, :assignment_status, :indexed_by, :terms + + def assignment_status + super.to_s.inquiry + end def indexed_by (super || default_indexed_by).inquiry end - def assignments - super.to_s.inquiry - end - def terms Array(super) end end def default_indexed_by - default_fields[:indexed_by] + self.class.default_values[:indexed_by] end def default_indexed_by? - indexed_by == default_indexed_by + default_value?(:indexed_by, indexed_by) end - - private - delegate :default_fields, to: :class, private: true end diff --git a/app/models/filter/params.rb b/app/models/filter/params.rb index 8938840eb..91970d5b9 100644 --- a/app/models/filter/params.rb +++ b/app/models/filter/params.rb @@ -1,34 +1,44 @@ module Filter::Params extend ActiveSupport::Concern - PERMITTED_PARAMS = [ :indexed_by, :assignments, bucket_ids: [], assignee_ids: [], assigner_ids: [], tag_ids: [], terms: [] ] + PERMITTED_PARAMS = [ :assignment_status, :indexed_by, assignee_ids: [], assigner_ids: [], bucket_ids: [], tag_ids: [], terms: [] ] + + class_methods do + def find_by_params(params) + find_by params_digest: digest_params(params) + end + + def digest_params(params) + Digest::MD5.hexdigest normalize_params(params).to_json + end + + def normalize_params(params) + params.to_h.compact_blank.reject(&method(:default_value?)).sort + end + end included do before_save { self.params_digest = self.class.digest_params(as_params) } end + # +as_params+ uses `resource#ids` instead of `#resource_ids` + # because the latter won't work on unpersisted filters. def as_params - @as_params ||= { - terms: terms, - tag_ids: tags.ids, - indexed_by: indexed_by, - bucket_ids: buckets.ids, - assignments: assignments, - assignee_ids: assignees.ids, - assigner_ids: assigners.ids - }.reject { |k, v| default_fields[k] == v }.compact_blank + {}.tap do |params| + params[:indexed_by] = indexed_by + params[:assignment_status] = assignment_status + params[:terms] = terms + params[:tag_ids] = tags.ids + params[:bucket_ids] = buckets.ids + params[:assignee_ids] = assignees.ids + params[:assigner_ids] = assigners.ids + end.compact_blank.reject(&method(:default_value?)) end - def to_params - ActionController::Parameters.new(as_params).permit(*PERMITTED_PARAMS).tap do |params| - params[:filter_id] = id if persisted? - end - end - - def params_without(key, value) - to_params.tap do |params| - params[key].delete(value) if params[key].is_a?(Array) - params.delete(key) if params[key] == value + def as_params_without(key, value) + as_params.tap do |params| + params[key].delete(value.to_i) if params[key].is_a?(Array) + params.delete(key) if params[key] == value.to_s end end end diff --git a/app/models/filter/resources.rb b/app/models/filter/resources.rb index bde1a30d1..537c52c35 100644 --- a/app/models/filter/resources.rb +++ b/app/models/filter/resources.rb @@ -17,6 +17,6 @@ module Filter::Resources end def buckets - creator.buckets.where id: bucket_ids + creator.buckets.where id: super.ids end end diff --git a/app/models/filter/summarized.rb b/app/models/filter/summarized.rb index b912967c0..fe65518d4 100644 --- a/app/models/filter/summarized.rb +++ b/app/models/filter/summarized.rb @@ -3,10 +3,6 @@ module Filter::Summarized [ index_summary, tag_summary, assignee_summary, assigner_summary, terms_summary ].compact.to_sentence + " #{bucket_summary}" end - def plain_summary - summary.remove(/<\/?mark>/) - end - private def index_summary indexed_by.humanize @@ -21,7 +17,7 @@ module Filter::Summarized def assignee_summary if assignees.any? "assigned to #{assignees.pluck(:name).to_choice_sentence}" - elsif assignments.unassigned? + elsif assignment_status.unassigned? "assigned to no one" end end diff --git a/app/views/bubbles/_filters.html.erb b/app/views/bubbles/_filters.html.erb index 75f3693b4..1538e22a2 100644 --- a/app/views/bubbles/_filters.html.erb +++ b/app/views/bubbles/_filters.html.erb @@ -17,32 +17,32 @@