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 +4 -4
- data/README.md +2 -1
- data/lib/forty_facets/facet_search.rb +13 -3
- data/lib/forty_facets/filter/facet_filter_definition.rb +20 -3
- data/lib/forty_facets/order_definition.rb +16 -1
- data/lib/forty_facets/version.rb +1 -1
- data/test/smoke_test.rb +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac056d5510aee76abee5c3eb5f277b3c8ff2c366
|
4
|
+
data.tar.gz: 55eb83dcb730ba5bbccd72b39bbc78eb2277c584
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f55aa94c15b85cef3f8450b21f53fa3597942969c6d9c1585e05e46c3ff9645d120114eba9b7b52ddd0bdac309420a9c69c53d4f98062f120f1427ed69c05c86
|
7
|
+
data.tar.gz: 7c62c3913a5f53c7bc5de3f0dc68338b96176821396adc26b83798989ff8f80eb2a80fea3153be199c76ea926a92b46e86705ffc2af76a70a55da0811b490181
|
data/README.md
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
[](https://travis-ci.org/fortytools/forty_facets)
|
2
2
|
[](https://coveralls.io/r/fortytools/forty_facets?branch=master)
|
3
3
|
[](https://codeclimate.com/github/fortytools/forty_facets)
|
4
|
+
[](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
|
-

|
10
|
+

|
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
|
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
|
-
|
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
|
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
|
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)).
|
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
|
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
|
data/lib/forty_facets/version.rb
CHANGED
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.
|
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:
|
11
|
+
date: 2015-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|