diff --git a/README.md b/README.md index 3f7a63b..e971745 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,8 @@ If you have Movies with a textual title, categotized by genre, studio and year w belongs_to :year belongs_to :studio has_and_belongs_to_many :genres + + scope :classics, -> { where("year <= ?", 1980) } end You can then declare the structure of your search like so: @@ -55,6 +57,7 @@ class HomeController < ApplicationController class MovieSearch < FortyFacets::FacetSearch model 'Movie' # which model to search for text :title # filter by a generic string entered by the user + scope :classics # only return movies which are in the scope 'classics' range :price, name: 'Price' # filter by ranges for decimal fields facet :year, name: 'Releaseyear', order: :year # additionally order values in the year field facet :studio, name: 'Studio', order: :name @@ -117,6 +120,7 @@ end | keyword | options | | |---------|---------------|-------------------------------------------------------------------------------------------------------------------------| | text | prefix:true | creates a filter to limit search result to entities containing the filter value in the given field | +| scope | | creates a filter to limit search result to entities matching the scope with the given name | | facet | | creates a facetted filter on the specified model attribute (attribute or belongs_to) | | range | | creates a range filter (param format 'FROM - TO') limiting result to entities with values in that range | | orders | | takes a hash mapping a label to an argument that the active record `order` method can be called with to sort the result | diff --git a/lib/forty_facets.rb b/lib/forty_facets.rb index 22d694b..539db86 100644 --- a/lib/forty_facets.rb +++ b/lib/forty_facets.rb @@ -9,6 +9,7 @@ module FortyFacets require "forty_facets/filter_definition" require "forty_facets/filter/range_filter_definition" require "forty_facets/filter/text_filter_definition" +require "forty_facets/filter/scope_filter_definition" require "forty_facets/filter/facet_filter_definition" require "forty_facets/filter/sql_facet_filter_definition" require "forty_facets/facet_search" diff --git a/lib/forty_facets/facet_search.rb b/lib/forty_facets/facet_search.rb index b93c05e..e40eafc 100644 --- a/lib/forty_facets/facet_search.rb +++ b/lib/forty_facets/facet_search.rb @@ -5,6 +5,7 @@ module FortyFacets # model 'Movie' # # text :title + # scope :someScope, name: 'Only very special' # range :price # facet :genre, name: 'Genre' # facet :year, name: 'Releaseyear', order: :year @@ -32,6 +33,10 @@ def text(path, opts = {}) definitions << TextFilterDefinition.new(self, path, opts) end + def scope(path, opts = {}) + definitions << ScopeFilterDefinition.new(self, path, opts) + end + def range(path, opts = {}) definitions << RangeFilterDefinition.new(self, path, opts) end diff --git a/lib/forty_facets/filter/scope_filter_definition.rb b/lib/forty_facets/filter/scope_filter_definition.rb new file mode 100644 index 0000000..ac19348 --- /dev/null +++ b/lib/forty_facets/filter/scope_filter_definition.rb @@ -0,0 +1,32 @@ +module FortyFacets + class ScopeFilterDefinition < FilterDefinition + class ScopeFilter < Filter + def active? + value == '1' + end + + def build_scope + return Proc.new { |base| base } unless active? + Proc.new { |base| base.send(definition.path.first) } + end + + def remove + new_params = search_instance.params || {} + new_params.delete(definition.request_param) + search_instance.class.new_unwrapped(new_params, search_instance.root) + end + + def add + new_params = search_instance.params || {} + new_params[definition.request_param] = '1' + search_instance.class.new_unwrapped(new_params, search_instance.root) + end + end + + def build_filter(search_instance, value) + ScopeFilter.new(self, search_instance, value) + end + + end +end + diff --git a/lib/forty_facets/version.rb b/lib/forty_facets/version.rb index 985c5e6..1639b92 100644 --- a/lib/forty_facets/version.rb +++ b/lib/forty_facets/version.rb @@ -1,3 +1,3 @@ module FortyFacets - VERSION = "0.1.0" + VERSION = "0.1.1" end diff --git a/test/smoke_test.rb b/test/smoke_test.rb index d21df3c..18edd15 100644 --- a/test/smoke_test.rb +++ b/test/smoke_test.rb @@ -28,6 +28,7 @@ class MovieSearch < FortyFacets::FacetSearch sql_facet({ classic: "year <= 1980", non_classic: "year > 1980" }, { name: "Classic" }) text [:studio, :description], name: 'Studio Description' + scope :classics, 'Name classics' end class SmokeTest < Minitest::Test @@ -267,4 +268,9 @@ def test_includes_does_not_blow_up search.filter(:studio).facet.reject(&:selected).to_a end + def test_scope_filter + search_with_scope = MovieSearch.new().filter(:classics).add + assert search_with_scope.result.count < Movie.count, 'Activating the scope should yield a smaller set of movies' + end + end