forty_facets 0.0.12 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 07d361e3522f559519b319bbf9ab5a2cb6fee8c4
4
- data.tar.gz: 6a6f27bfd267c8b8a21c9e1ec5b77a2883356995
3
+ metadata.gz: ac056d5510aee76abee5c3eb5f277b3c8ff2c366
4
+ data.tar.gz: 55eb83dcb730ba5bbccd72b39bbc78eb2277c584
5
5
  SHA512:
6
- metadata.gz: 2655be1f82d5586732b1621e870583b5411c58858094f55b80ee5162ebfe17174ee94cafd2c2be0cc13beb974c4190c2bfa643381eea9175059b51bbda75e17c
7
- data.tar.gz: 2df7bce842612f53ac3fa3f3b5e33c36c9dbc21e8747cd1e0d526afc80249a7f2c6c797f25cb4f057c2cb0123a231c6419f95bc45b1fe2a9136949906a5d321f
6
+ metadata.gz: f55aa94c15b85cef3f8450b21f53fa3597942969c6d9c1585e05e46c3ff9645d120114eba9b7b52ddd0bdac309420a9c69c53d4f98062f120f1427ed69c05c86
7
+ data.tar.gz: 7c62c3913a5f53c7bc5de3f0dc68338b96176821396adc26b83798989ff8f80eb2a80fea3153be199c76ea926a92b46e86705ffc2af76a70a55da0811b490181
data/README.md CHANGED
@@ -1,12 +1,13 @@
1
1
  [![Build Status](https://travis-ci.org/fortytools/forty_facets.svg)](https://travis-ci.org/fortytools/forty_facets)
2
2
  [![Coverage Status](https://coveralls.io/repos/fortytools/forty_facets/badge.png?branch=master)](https://coveralls.io/r/fortytools/forty_facets?branch=master)
3
3
  [![Code Climate](https://codeclimate.com/github/fortytools/forty_facets.png)](https://codeclimate.com/github/fortytools/forty_facets)
4
+ [![forty_facets API Documentation](https://www.omniref.com/ruby/gems/forty_facets.png)](https://www.omniref.com/ruby/gems/forty_facets)
4
5
 
5
6
  # FortyFacets
6
7
 
7
8
  FortyFacets lets you easily build explorative search interfaces based on fields of your ActiveRecord models.
8
9
 
9
- ![demo](demo.gif)
10
+ ![demo](https://raw.githubusercontent.com/fortytools/forty_facets/master/demo.gif)
10
11
 
11
12
  See it implemented in a [example rails application](https://github.com/fortytools/forty_facets_demo) or
12
13
  try a [working demo](http://forty-facets-demo.herokuapp.com/ "Testinstallation on heroku")!
@@ -12,7 +12,8 @@ module FortyFacets
12
12
  #
13
13
  # orders 'Title' => :title,
14
14
  # 'price, cheap first' => "price asc",
15
- # 'price, expensive first' => {price: :desc, title: :desc}
15
+ # 'price, expensive first' => {price: :desc, title: :desc},
16
+ # 'Title, reverse' => {order: "title desc", default: true}
16
17
  #
17
18
  # end
18
19
  class FacetSearch
@@ -78,6 +79,11 @@ module FortyFacets
78
79
  orders << definition.build(self, params[:order])
79
80
  end
80
81
 
82
+ unless @orders.find(&:active)
83
+ default_order = @orders.find {|o| o.definition.default}
84
+ default_order.active = true if default_order
85
+ end
86
+
81
87
  @root = root
82
88
  end
83
89
 
@@ -100,7 +106,7 @@ module FortyFacets
100
106
  filter.build_scope.call(previous)
101
107
  end
102
108
  query = query.order(order.definition.clause) if order
103
- query.uniq
109
+ query
104
110
  end
105
111
 
106
112
  def wrapped_params
@@ -117,7 +123,7 @@ module FortyFacets
117
123
  end
118
124
 
119
125
  def path
120
- unfiltered? ? '?' : '?' + wrapped_params.to_param
126
+ '?' + wrapped_params.to_param
121
127
  end
122
128
 
123
129
  def unfiltered?
@@ -128,6 +134,10 @@ module FortyFacets
128
134
  @root || self.class.root_scope
129
135
  end
130
136
 
137
+ def change_root new_root
138
+ @root = new_root
139
+ end
140
+
131
141
  private
132
142
 
133
143
  def request_to_search_params(request_params)
@@ -54,13 +54,21 @@ module FortyFacets
54
54
 
55
55
  def build_scope
56
56
  return Proc.new { |base| base } if empty?
57
- Proc.new { |base| base.joins(definition.joins).where(definition.qualified_column_name => value) }
57
+ Proc.new do |base|
58
+ result = base.joins(definition.joins).where(definition.qualified_column_name => value)
59
+ if definition.joins
60
+ result = result.distinct
61
+ end
62
+
63
+ result
64
+ end
58
65
  end
59
66
 
60
67
  def facet
61
68
  my_column = definition.qualified_column_name
62
69
  query = "#{my_column} AS facet_value, count(#{my_column}) AS occurrences"
63
70
  counts = without.result.reorder('').joins(definition.joins).select(query).group(my_column)
71
+ counts.includes_values = []
64
72
  facet = counts.map do |c|
65
73
  is_selected = selected.include?(c.facet_value)
66
74
  FacetValue.new(c.facet_value, c.occurrences, is_selected)
@@ -89,13 +97,21 @@ module FortyFacets
89
97
  class BelongsToFilter < AssociationFacetFilter
90
98
  def build_scope
91
99
  return Proc.new { |base| base } if empty?
92
- Proc.new { |base| base.joins(definition.joins).where(definition.qualified_column_name => values) }
100
+ Proc.new do |base|
101
+ result = base.joins(definition.joins).where(definition.qualified_column_name => values)
102
+ if definition.joins
103
+ result = result.distinct
104
+ end
105
+
106
+ result
107
+ end
93
108
  end
94
109
 
95
110
  def facet
96
111
  my_column = definition.qualified_column_name
97
112
  query = "#{my_column} AS foreign_id, count(#{my_column}) AS occurrences"
98
113
  counts = without.result.reorder('').joins(definition.joins).select(query).group(my_column)
114
+ counts.includes_values = []
99
115
  entities_by_id = definition.association.klass.find(counts.map(&:foreign_id)).group_by(&:id)
100
116
 
101
117
  facet = counts.map do |count|
@@ -120,7 +136,7 @@ module FortyFacets
120
136
  subquery = base.joins(definition.joins).select(primary_key_column)
121
137
  .where("#{join_name}.#{definition.association.foreign_key}" => values).uniq
122
138
 
123
- base.joins(definition.joins).where(primary_key_column => subquery.select(primary_key_column)).uniq
139
+ base.joins(definition.joins).where(primary_key_column => subquery.select(primary_key_column)).distinct
124
140
  end
125
141
  end
126
142
 
@@ -134,6 +150,7 @@ module FortyFacets
134
150
  .joins(definition.joins)
135
151
  .select("#{my_column} as foreign_id, count(#{my_column}) as occurrences")
136
152
  .group(my_column)
153
+ counts.includes_values = []
137
154
  entities_by_id = definition.association.klass.find(counts.map(&:foreign_id)).group_by(&:id)
138
155
 
139
156
  facet = counts.map do |count|
@@ -1,6 +1,21 @@
1
1
  module FortyFacets
2
2
  # Stores the parameters of a order criteria for a search.
3
- OrderDefinition = Struct.new(:title, :clause) do
3
+ class OrderDefinition
4
+ attr(:title, :clause, :default)
5
+
6
+ def initialize title, clause
7
+ @title = title
8
+ @clause = clause
9
+ @default = false
10
+
11
+ if clause.is_a? Hash
12
+ if clause[:order] && clause[:default]
13
+ @clause = clause[:order]
14
+ @default = clause[:default]
15
+ end
16
+ end
17
+ end
18
+
4
19
  def build(search, order_param)
5
20
  Order.new(search, self, order_param == title.to_s)
6
21
  end
@@ -1,3 +1,3 @@
1
1
  module FortyFacets
2
- VERSION = "0.0.12"
2
+ VERSION = "0.0.13"
3
3
  end
data/test/smoke_test.rb CHANGED
@@ -213,4 +213,10 @@ class SmokeTest < Minitest::Test
213
213
 
214
214
  end
215
215
 
216
+ def test_includes_does_not_blow_up
217
+ selected_genre = Genre.first
218
+ search = MovieSearch.new({}, Movie.all.includes(:studio)).filter(:genres).add(selected_genre)
219
+ search.filter(:studio).facet.reject(&:selected).to_a
220
+ end
221
+
216
222
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forty_facets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Axel Tetzlaff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-29 00:00:00.000000000 Z
11
+ date: 2015-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler