Skip to content

Commit

Permalink
Merge pull request #3 from fortytools/hops
Browse files Browse the repository at this point in the history
Allow filters to be specified on entities some 'hops' away
  • Loading branch information
axelerator committed Sep 25, 2014
2 parents 943fa9d + be9244a commit 3753acb
Show file tree
Hide file tree
Showing 14 changed files with 324 additions and 334 deletions.
5 changes: 1 addition & 4 deletions lib/forty_facets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ module FortyFacets
require "forty_facets/order"
require "forty_facets/filter"
require "forty_facets/filter_definition"
require "forty_facets/filter/belongs_to_filter_definition"
require "forty_facets/filter/belongs_to_chain_filter_definition"
require "forty_facets/filter/has_many_filter_definition"
require "forty_facets/filter/range_filter_definition"
require "forty_facets/filter/text_filter_definition"
require "forty_facets/filter/attribute_filter_definition"
require "forty_facets/filter/facet_filter_definition"
require "forty_facets/facet_search"
40 changes: 15 additions & 25 deletions lib/forty_facets/facet_search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,24 @@ class FacetSearch
attr_reader :filters, :orders

class << self
def model(model_name)
@model_name = model_name
def model(model)
if model.is_a? Class
@root_class = model
else
@root_class = Kernel.const_get(model)
end
end

def text(model_field, opts = {})
definitions << TextFilterDefinition.new(self, model_field, opts)
def text(path, opts = {})
definitions << TextFilterDefinition.new(self, path, opts)
end

def range(model_field, opts = {})
definitions << RangeFilterDefinition.new(self, model_field, opts)
def range(path, opts = {})
definitions << RangeFilterDefinition.new(self, path, opts)
end

def facet(model_field, opts = {})
if model_field.is_a? Array
definitions << BelongsToChainFilterDefinition.new(self, model_field, opts)
else
reflection = self.root_class.reflect_on_association(model_field)
if reflection
if reflection.macro == :belongs_to
definitions << BelongsToFilterDefinition.new(self, model_field, opts)
else
definitions << HasManyFilterDefinition.new(self, model_field, opts)
end
else
definitions << AttributeFilterDefinition.new(self, model_field, opts)
end
end
def facet(path, opts = {})
definitions << FacetFilterDefinition.new(self, path, opts)
end

def orders(name_and_order_options)
Expand All @@ -57,8 +48,7 @@ def definitions
end

def root_class
raise 'No model given' unless @model_name
Kernel.const_get(@model_name)
@root_class || raise('No model class given')
end

def root_scope
Expand Down Expand Up @@ -96,7 +86,7 @@ def self.new_unwrapped(params, root)
end

def filter(filter_name)
filter = @filters.find { |f| f.filter_definition.model_field == filter_name }
filter = @filters.find { |f| f.definition.path == [filter_name].flatten }
raise "Unknown filter #{filter_name}" unless filter
filter
end
Expand All @@ -119,7 +109,7 @@ def wrapped_params

def params
params = @filters.inject({}) do |sum, filter|
sum[filter.filter_definition.request_param] = filter.value.dup unless filter.empty?
sum[filter.definition.request_param] = filter.value.dup unless filter.empty?
sum
end
params[:order] = order.definition.request_value if order
Expand Down
32 changes: 6 additions & 26 deletions lib/forty_facets/filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ module FortyFacets
# Base class for the objects representing a specific value for a specific
# type of filter. Most FilterDefinitions will have their own Filter subclass
# to control values for display and rendering to request parameters.
Filter = Struct.new(:filter_definition, :search_instance, :value) do
Filter = Struct.new(:definition, :search_instance, :value) do

FacetValue = Struct.new(:entity, :count, :selected)

def name
filter_definition.options[:name] || filter_definition.model_field
definition.options[:name] || definition.path.join(' ')
end

def empty?
Expand All @@ -16,33 +19,10 @@ def without
search = search_instance
return search if empty?
new_params = search_instance.params || {}
new_params.delete(filter_definition.request_param)
new_params.delete(definition.request_param)
search_instance.class.new_unwrapped(new_params, search_instance.root)
end
end

# Base class for filter with multiple values and grouped facet values
class FacetFilter < Filter
def values
@values ||= Array.wrap(value).sort.uniq
end

protected

def order_facet!(facet)
order_accessor = filter_definition.options[:order]
if order_accessor
if order_accessor.is_a?(Proc)
facet.sort_by!{|facet_value| order_accessor.call(facet_value.entity) }
else
facet.sort_by!{|facet_value| facet_value.entity.send(order_accessor) }
end
else
facet.sort_by!{|facet_value| -facet_value.count }
end
facet
end

end
end

46 changes: 0 additions & 46 deletions lib/forty_facets/filter/attribute_filter_definition.rb

This file was deleted.

86 changes: 0 additions & 86 deletions lib/forty_facets/filter/belongs_to_chain_filter_definition.rb

This file was deleted.

58 changes: 0 additions & 58 deletions lib/forty_facets/filter/belongs_to_filter_definition.rb

This file was deleted.

Loading

0 comments on commit 3753acb

Please sign in to comment.