listings 0.1.4 → 0.1.5
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.
- data/README.md +66 -0
- data/app/assets/javascripts/listings.js +37 -6
- data/app/controllers/listings/listings_controller.rb +5 -2
- data/app/views/listings/_listing.html.haml +1 -1
- data/app/views/listings/_table_content.html.haml +1 -1
- data/app/views/listings/twitter-bootstrap-2/_side_filters.html.haml +1 -1
- data/app/views/listings/twitter-bootstrap-2/_top_filters.html.haml +1 -1
- data/app/views/listings/twitter-bootstrap-3/_side_filters.html.haml +1 -1
- data/app/views/listings/twitter-bootstrap-3/_top_filters.html.haml +1 -1
- data/lib/listings/action_view_extensions.rb +8 -2
- data/lib/listings/base.rb +15 -3
- data/lib/listings/base_field_view.rb +4 -0
- data/lib/listings/configuration.rb +2 -0
- data/lib/listings/configuration_methods.rb +7 -1
- data/lib/listings/custom_filter_descriptor.rb +19 -0
- data/lib/listings/custom_filter_view.rb +25 -0
- data/lib/listings/filter_descriptor.rb +4 -0
- data/lib/listings/filter_view.rb +8 -0
- data/lib/listings/kaminari_helpers_tag_patch.rb +17 -8
- data/lib/listings/rspec.rb +5 -0
- data/lib/{rspec → listings/rspec}/listings_helpers.rb +0 -0
- data/lib/listings/sources/active_record_data_source.rb +29 -15
- data/lib/listings/sources/data_source.rb +4 -0
- data/lib/listings/sources/object_data_source.rb +4 -0
- data/lib/listings/version.rb +1 -1
- data/lib/listings/view_helper_methods.rb +2 -0
- data/spec/dummy/app/listings/tracks_listing.rb +5 -0
- data/spec/dummy/config/initializers/listings.rb +3 -0
- data/spec/dummy/db/seeds.rb +4 -1
- data/spec/factories/tracks.rb +2 -2
- data/spec/factories/traits.rb +4 -0
- data/spec/lib/filter_parser_spec.rb +7 -1
- data/spec/spec_helper.rb +1 -2
- metadata +8 -10
- data/lib/rspec.rb +0 -1
data/README.md
CHANGED
@@ -22,6 +22,7 @@ A listing data source have built in support for ActiveRecord and Arrays.
|
|
22
22
|
* [paginates_per](#paginates_per)
|
23
23
|
* [export](#export)
|
24
24
|
* [css](#css)
|
25
|
+
* [Testing](#testing)
|
25
26
|
* [i18n](#i18n)
|
26
27
|
* [Templates](#templates)
|
27
28
|
* [Javascript api](#javascript-api)
|
@@ -63,6 +64,7 @@ Create `config/initializers/listings.rb` file to make general configurations. Li
|
|
63
64
|
# file: config/initializers/listings.rb
|
64
65
|
Listings.configure do |config|
|
65
66
|
config.theme = 'twitter-bootstrap-3' # defaults to 'twitter-bootstrap-2'
|
67
|
+
config.push_url = true # User html5 history push_state to allow back/forward navigation. defaults to false
|
66
68
|
end
|
67
69
|
```
|
68
70
|
|
@@ -241,12 +243,26 @@ It supports `title:` and a block
|
|
241
243
|
end
|
242
244
|
```
|
243
245
|
|
246
|
+
Also `render:` option can be used to suppress the rendering of the filter, but allowing the user to filter by it. For example to filter by the id:
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
filter :id, render: false
|
250
|
+
```
|
251
|
+
|
244
252
|
Filters are rendered by default by the side of the listing. With `layout` method you can change this and render them on the top.
|
245
253
|
|
246
254
|
```ruby
|
247
255
|
layout filters: :top
|
248
256
|
```
|
249
257
|
|
258
|
+
Custom filters allows definition of custom meaning to a key. This filters are not rendered.
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
custom_filter :order_lte do |items, value|
|
262
|
+
items.where('"order" <= ?', value.to_i)
|
263
|
+
end
|
264
|
+
```
|
265
|
+
|
250
266
|
### paginates_per
|
251
267
|
|
252
268
|
Page size can be specified by `paginates_per`
|
@@ -303,6 +319,32 @@ A `column` also support a `class` option to specify a css class to be applied on
|
|
303
319
|
column :title, class: 'title-style'
|
304
320
|
```
|
305
321
|
|
322
|
+
## Testing
|
323
|
+
|
324
|
+
Include `listings/rspec` in your `spec_helper.rb`
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
# file: spec/spec_helper.rb
|
328
|
+
require 'listings/rspec'
|
329
|
+
```
|
330
|
+
|
331
|
+
Ensure listing is able to render
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
# file: spec/listings/tracks_listing_spec.rb
|
335
|
+
require 'spec_helper'
|
336
|
+
|
337
|
+
RSpec.describe TracksListing, type: :listing do
|
338
|
+
let(:listing) { query_listing :tracks }
|
339
|
+
|
340
|
+
it 'should get tracks' do
|
341
|
+
# ... data setup ...
|
342
|
+
items = listing.items.to_a
|
343
|
+
# ... assert expected items ...
|
344
|
+
end
|
345
|
+
end
|
346
|
+
```
|
347
|
+
|
306
348
|
## i18n
|
307
349
|
|
308
350
|
Although titles can be specified in the listing definition, i18n support is available. Add to your locales:
|
@@ -336,6 +378,30 @@ use
|
|
336
378
|
refreshListing('tracks')
|
337
379
|
```
|
338
380
|
|
381
|
+
Change filters
|
382
|
+
|
383
|
+
```
|
384
|
+
$('#tracks.listings').trigger("listings:filter:key:clear", 'album_name')
|
385
|
+
$('#tracks.listings').trigger("listings:filter:key:set", ['album_name', 'Best of'])
|
386
|
+
```
|
387
|
+
|
388
|
+
## View Helpers
|
389
|
+
|
390
|
+
Use `render_listing` helper to include the listing by its `name`.
|
391
|
+
|
392
|
+
```
|
393
|
+
= render_listing :tracks
|
394
|
+
```
|
395
|
+
|
396
|
+
Use `listings_link_to_filter` helper to render a link that will set a filter. Used to example when you want the user to be able to click on a cell value to filter upon that.
|
397
|
+
|
398
|
+
```ruby
|
399
|
+
column artist: :name do |album, value|
|
400
|
+
listings_link_to_filter(value, :artist_id, album.artist_id)
|
401
|
+
end
|
402
|
+
```
|
403
|
+
|
404
|
+
|
339
405
|
## Templates
|
340
406
|
|
341
407
|
There are a number of templates involved in rendering the listing. These templates can be rendered by the hosting app per listing or theme basis.
|
@@ -120,20 +120,17 @@ $(function(){
|
|
120
120
|
$('.listing').on('click', 'a.filter, .filter a', function(e) {
|
121
121
|
elem = $(this);
|
122
122
|
var listingElement = elem.closest('.listing');
|
123
|
-
clearSelectedItems(listingElement);
|
124
|
-
|
125
123
|
var key = elem.data('key');
|
126
124
|
var value = elem.data('value');
|
127
125
|
|
128
126
|
var search_data = listingElement.data('search');
|
129
127
|
if (search_data.filters[key] == value) {
|
130
|
-
|
128
|
+
listingElement.trigger("listings:filter:key:clear", key)
|
131
129
|
} else {
|
132
|
-
|
130
|
+
listingElement.trigger("listings:filter:key:set", [key, value])
|
133
131
|
}
|
134
132
|
|
135
|
-
|
136
|
-
updateListingFromSearchData(listingElement);
|
133
|
+
e.preventDefault();
|
137
134
|
}).on("listings:loaded", function(e){
|
138
135
|
// highlight current filter
|
139
136
|
var listingElement = $(this).closest('.listing');
|
@@ -145,8 +142,42 @@ $(function(){
|
|
145
142
|
listingElement.find(filerLinkSelector).closest('.filter').addClass('active');
|
146
143
|
}
|
147
144
|
|
145
|
+
if (listingElement.data('config').push_url && listingElement.data('skip-push-url') !== true) {
|
146
|
+
listingElement.data('skip-push-url', false);
|
147
|
+
var url = listingElement.data('url');
|
148
|
+
var queryStringStart = url.indexOf('?');
|
149
|
+
var queryString = queryStringStart == -1 ? '' : url.substring(queryStringStart);
|
150
|
+
history.pushState({listing: '#' + listingElement.attr('id')}, document.title, location.href.split('?')[0] + queryString);
|
151
|
+
}
|
152
|
+
|
153
|
+
}).on("listings:filter:key:set", function(event, key, value) {
|
154
|
+
var listingElement = $(this).closest('.listing');
|
155
|
+
clearSelectedItems(listingElement);
|
156
|
+
|
157
|
+
var search_data = listingElement.data('search');
|
158
|
+
search_data.filters[key] = value;
|
159
|
+
listingElement.data('search', search_data);
|
160
|
+
|
161
|
+
updateListingFromSearchData(listingElement);
|
162
|
+
}).on("listings:filter:key:clear", function(event, key) {
|
163
|
+
var listingElement = $(this).closest('.listing');
|
164
|
+
clearSelectedItems(listingElement);
|
165
|
+
|
166
|
+
var search_data = listingElement.data('search');
|
167
|
+
delete search_data.filters[key];
|
168
|
+
listingElement.data('search', search_data);
|
169
|
+
|
170
|
+
updateListingFromSearchData(listingElement);
|
148
171
|
});
|
149
172
|
|
173
|
+
window.onpopstate = function(event) {
|
174
|
+
if (event.state && event.state.listing) {
|
175
|
+
var listing = $(event.state.listing);
|
176
|
+
listing.data('skip-push-url', true);
|
177
|
+
$.get(listing.data('url').split('?')[0] + '?' + document.location.href.split('?')[1]);
|
178
|
+
}
|
179
|
+
};
|
180
|
+
|
150
181
|
function searchEscape(value) {
|
151
182
|
if (value.toString().indexOf(" ") == -1) {
|
152
183
|
return value;
|
@@ -16,8 +16,11 @@ module Listings
|
|
16
16
|
@listing = prepare_listing params, view_context, false
|
17
17
|
|
18
18
|
respond_to do |format|
|
19
|
-
format.csv { send_data @listing.to_csv, filename:
|
20
|
-
format.xls
|
19
|
+
format.csv { send_data @listing.to_csv, filename: @listing.export_filename(:csv) }
|
20
|
+
format.xls do
|
21
|
+
headers["Content-Disposition"] = "attachment; filename=\"#{@listing.export_filename(:xls)}\""
|
22
|
+
render 'listings/export'
|
23
|
+
end
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
.listing{:id => listing.name, :'data-url' => listing.url, :'data-search' => listing.search_data.to_json }
|
1
|
+
.listing{:id => listing.name, :'data-url' => listing.url, :'data-search' => listing.search_data.to_json, :'data-config' => listing.client_config.to_json }
|
2
2
|
= listings_partial_render 'table_full', listing
|
3
3
|
|
4
4
|
:javascript
|
@@ -5,7 +5,13 @@ module Listings
|
|
5
5
|
options.reverse_merge! :params => {}
|
6
6
|
params_for_listing = {:listing => key}.merge(params).merge(options[:params]).with_indifferent_access
|
7
7
|
listing = prepare_listing(params_for_listing, self)
|
8
|
-
listings_partial_render 'listing', listing
|
8
|
+
res = listings_partial_render 'listing', listing
|
9
|
+
Kaminari::Helpers::Tag.paginate_with_listings(nil)
|
10
|
+
res
|
11
|
+
end
|
12
|
+
|
13
|
+
def listings_link_to_filter(text, key, value)
|
14
|
+
link_to text, '#', onclick: "$(this).closest('.listing').trigger('listings:filter:key:set', ['#{key}', '#{escape_javascript(value)}']);return false;"
|
9
15
|
end
|
10
16
|
|
11
17
|
def listings_partial_render(view, listing, options = {})
|
@@ -22,7 +28,7 @@ module Listings
|
|
22
28
|
params.delete :controller
|
23
29
|
params.delete :action
|
24
30
|
|
25
|
-
Kaminari::Helpers::Tag.
|
31
|
+
Kaminari::Helpers::Tag.paginate_with_listings(view_context.listings)
|
26
32
|
|
27
33
|
listing_class = lookup_listing_class(params[:listing])
|
28
34
|
listing_class.new.tap do |listing|
|
data/lib/listings/base.rb
CHANGED
@@ -46,7 +46,7 @@ module Listings
|
|
46
46
|
|
47
47
|
def parse_filter(text, filter_keys)
|
48
48
|
filters = {}
|
49
|
-
filter_keys.each do |key|
|
49
|
+
filter_keys.sort_by {|k| -k.length }.each do |key|
|
50
50
|
text = collect_filter text, key, filters
|
51
51
|
end
|
52
52
|
|
@@ -88,12 +88,12 @@ module Listings
|
|
88
88
|
end
|
89
89
|
|
90
90
|
if filterable?
|
91
|
-
|
91
|
+
filters_to_render.each do |filter_view|
|
92
92
|
filter_view.values # prepare values
|
93
93
|
end
|
94
94
|
|
95
95
|
self.search_filters.each do |key, filter_value|
|
96
|
-
|
96
|
+
filter_with_key(key).apply_filter(filter_value)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -217,5 +217,17 @@ module Listings
|
|
217
217
|
def theme
|
218
218
|
Listings.configuration.theme
|
219
219
|
end
|
220
|
+
|
221
|
+
def export_filename(format)
|
222
|
+
"#{kind.gsub(' ', '_')}_#{Time.now.to_s.gsub(' ', '_')}.#{format}"
|
223
|
+
end
|
224
|
+
|
225
|
+
def filters_to_render
|
226
|
+
filters.select { |f| f.render? }
|
227
|
+
end
|
228
|
+
|
229
|
+
def client_config
|
230
|
+
{ push_url: Listings.configuration.push_url }
|
231
|
+
end
|
220
232
|
end
|
221
233
|
end
|
@@ -13,9 +13,11 @@ module Listings
|
|
13
13
|
|
14
14
|
class Configuration
|
15
15
|
attr_accessor :theme
|
16
|
+
attr_accessor :push_url # use html5 pushState to allow back navigation of listings. default false.
|
16
17
|
|
17
18
|
def initialize
|
18
19
|
@theme = 'twitter-bootstrap-2'
|
20
|
+
@push_url = false
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -5,6 +5,8 @@ require 'listings/column_descriptor'
|
|
5
5
|
require 'listings/column_view'
|
6
6
|
require 'listings/filter_descriptor'
|
7
7
|
require 'listings/filter_view'
|
8
|
+
require 'listings/custom_filter_descriptor'
|
9
|
+
require 'listings/custom_filter_view'
|
8
10
|
|
9
11
|
module Listings
|
10
12
|
module ConfigurationMethods
|
@@ -57,7 +59,7 @@ module Listings
|
|
57
59
|
|
58
60
|
def filters
|
59
61
|
@filters ||= self.class.filters.map do |fd|
|
60
|
-
|
62
|
+
fd.build(self)
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
@@ -162,6 +164,10 @@ module Listings
|
|
162
164
|
filters << FilterDescriptor.new(path, props, proc)
|
163
165
|
end
|
164
166
|
|
167
|
+
def custom_filter(key, &proc)
|
168
|
+
filters << CustomFilterDescriptor.new(key, proc)
|
169
|
+
end
|
170
|
+
|
165
171
|
def layout(props = {})
|
166
172
|
@layout_options = props
|
167
173
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Listings
|
2
|
+
class CustomFilterDescriptor
|
3
|
+
attr_reader :key
|
4
|
+
attr_reader :proc
|
5
|
+
|
6
|
+
def initialize(key, proc)
|
7
|
+
@key = key
|
8
|
+
@proc = proc
|
9
|
+
end
|
10
|
+
|
11
|
+
def build(listing)
|
12
|
+
CustomFilterView.new(listing, self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def apply_filter(value)
|
16
|
+
data_source.filter(field, value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Listings
|
2
|
+
class CustomFilterView
|
3
|
+
attr_reader :listing
|
4
|
+
attr_reader :descriptor
|
5
|
+
|
6
|
+
def initialize(listing, descriptor)
|
7
|
+
@listing = listing
|
8
|
+
@descriptor = descriptor
|
9
|
+
end
|
10
|
+
|
11
|
+
def key
|
12
|
+
@descriptor.key
|
13
|
+
end
|
14
|
+
|
15
|
+
def render?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def apply_filter(value)
|
20
|
+
listing.data_source.transform_items do |items|
|
21
|
+
listing.instance_exec items, value, &@descriptor.proc
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/listings/filter_view.rb
CHANGED
@@ -1,20 +1,29 @@
|
|
1
1
|
module Kaminari
|
2
2
|
module Helpers
|
3
3
|
class Tag
|
4
|
+
def self.paginate_with_listings(val)
|
5
|
+
Thread.current[:listings] = val
|
6
|
+
end
|
4
7
|
|
5
|
-
def self.
|
6
|
-
|
8
|
+
def self.listings_to_paginate_with
|
9
|
+
Thread.current[:listings]
|
7
10
|
end
|
8
11
|
|
9
12
|
# patch kaminari helpers
|
10
13
|
# passing options of mountable engine routes seems to not be working
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
def page_url_for_with_listing(page)
|
15
|
+
if Kaminari::Helpers::Tag.listings_to_paginate_with
|
16
|
+
@params.delete :page
|
17
|
+
params = {@param_name => page}.merge(@params).with_indifferent_access
|
18
|
+
params.delete :controller
|
19
|
+
params.delete :action
|
20
|
+
Kaminari::Helpers::Tag.listings_to_paginate_with.listing_content_url(params)
|
21
|
+
else
|
22
|
+
page_url_for_without_listing(page)
|
23
|
+
end
|
17
24
|
end
|
25
|
+
|
26
|
+
alias_method_chain :page_url_for, :listing
|
18
27
|
end
|
19
28
|
end
|
20
29
|
end
|
File without changes
|
@@ -29,6 +29,10 @@ module Listings::Sources
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def transform_items
|
33
|
+
@items = yield @items
|
34
|
+
end
|
35
|
+
|
32
36
|
def scope
|
33
37
|
@items = yield @items
|
34
38
|
@items_for_filter = yield @items_for_filter
|
@@ -39,7 +43,7 @@ module Listings::Sources
|
|
39
43
|
end
|
40
44
|
|
41
45
|
def values_for_filter(field)
|
42
|
-
|
46
|
+
field.all_values(@items_for_filter)
|
43
47
|
end
|
44
48
|
|
45
49
|
def search(fields, value)
|
@@ -62,7 +66,6 @@ module Listings::Sources
|
|
62
66
|
|
63
67
|
def joins(relation)
|
64
68
|
@items = @items.eager_load(relation)
|
65
|
-
@items_for_filter = @items_for_filter.joins(relation)
|
66
69
|
end
|
67
70
|
|
68
71
|
def build_field(path)
|
@@ -89,10 +92,28 @@ module Listings::Sources
|
|
89
92
|
end
|
90
93
|
end
|
91
94
|
|
92
|
-
class
|
95
|
+
class BaseActiveRecordField < Field
|
93
96
|
delegate :connection, to: :data_source
|
94
97
|
delegate :quote_table_name, :quote_column_name, to: :connection
|
95
98
|
|
99
|
+
def initialize(data_source)
|
100
|
+
super(data_source)
|
101
|
+
end
|
102
|
+
|
103
|
+
def all_values(items)
|
104
|
+
prepare_pluck(items).reorder(query_column).pluck("distinct #{query_column}").reject(&:nil?)
|
105
|
+
end
|
106
|
+
|
107
|
+
def prepare_pluck(items)
|
108
|
+
items
|
109
|
+
end
|
110
|
+
|
111
|
+
def sort(items, direction)
|
112
|
+
items.reorder("#{query_column} #{direction}")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class ActiveRecordField < BaseActiveRecordField
|
96
117
|
def initialize(attribute_name, data_source)
|
97
118
|
super(data_source)
|
98
119
|
@attribute_name = attribute_name
|
@@ -106,10 +127,6 @@ module Listings::Sources
|
|
106
127
|
"#{quote_table_name(data_source.items.table_name)}.#{quote_column_name(@attribute_name)}"
|
107
128
|
end
|
108
129
|
|
109
|
-
def sort(items, direction)
|
110
|
-
items.reorder("#{query_column} #{direction}")
|
111
|
-
end
|
112
|
-
|
113
130
|
def key
|
114
131
|
@attribute_name.to_s
|
115
132
|
end
|
@@ -119,10 +136,7 @@ module Listings::Sources
|
|
119
136
|
end
|
120
137
|
end
|
121
138
|
|
122
|
-
class ActiveRecordAssociationField <
|
123
|
-
delegate :connection, to: :data_source
|
124
|
-
delegate :quote_table_name, :quote_column_name, to: :connection
|
125
|
-
|
139
|
+
class ActiveRecordAssociationField < BaseActiveRecordField
|
126
140
|
def initialize(path, data_source)
|
127
141
|
super(data_source)
|
128
142
|
@path = path
|
@@ -130,6 +144,10 @@ module Listings::Sources
|
|
130
144
|
data_source.joins(path[0])
|
131
145
|
end
|
132
146
|
|
147
|
+
def prepare_pluck(items)
|
148
|
+
items.joins(@path[0])
|
149
|
+
end
|
150
|
+
|
133
151
|
def value_for(item)
|
134
152
|
result = item
|
135
153
|
@path.each do |attribute_name|
|
@@ -144,10 +162,6 @@ module Listings::Sources
|
|
144
162
|
"#{quote_table_name(association.reflection.table_name)}.#{quote_column_name(@path[1])}"
|
145
163
|
end
|
146
164
|
|
147
|
-
def sort(items, direction)
|
148
|
-
items.reorder("#{query_column} #{direction}")
|
149
|
-
end
|
150
|
-
|
151
165
|
def key
|
152
166
|
@path.join('_')
|
153
167
|
end
|
@@ -8,6 +8,10 @@ module Listings::Sources
|
|
8
8
|
def items
|
9
9
|
end
|
10
10
|
|
11
|
+
# free transform items. used usually to filter the result with logic given by a block
|
12
|
+
def transform_items
|
13
|
+
end
|
14
|
+
|
11
15
|
# applies filter to the items
|
12
16
|
# scope will be called with a block with the ongoing items
|
13
17
|
# the result of the block is used as the narrowed items
|
data/lib/listings/version.rb
CHANGED
@@ -19,6 +19,8 @@ module Listings
|
|
19
19
|
view_context.listings.listing_export_url build_params(:format => format)
|
20
20
|
end
|
21
21
|
|
22
|
+
# TODO add url_for_filter that will build the search string
|
23
|
+
|
22
24
|
def build_params(more_params)
|
23
25
|
res = view_context.params.merge(:listing => self.name).merge(params).merge(more_params)
|
24
26
|
res.delete param_page
|
@@ -6,6 +6,11 @@ class TracksListing < Listings::Base
|
|
6
6
|
filter album: :id, title: 'The Album Id' do |value|
|
7
7
|
"#{value}!"
|
8
8
|
end
|
9
|
+
filter :order, render: false
|
10
|
+
|
11
|
+
custom_filter :order_lte do |items, value|
|
12
|
+
items.where('"order" <= ?', value.to_i)
|
13
|
+
end
|
9
14
|
|
10
15
|
column :order
|
11
16
|
column :title, searchable: true
|
data/spec/dummy/db/seeds.rb
CHANGED
@@ -5,7 +5,10 @@ require 'factory_girl'
|
|
5
5
|
Post.create! title: "post n-#{sn}", author: "john-#{(sn % 4) + 1}", category: "category-#{(sn % 3) + 1}"
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
8
|
(1..10).each do |sn|
|
10
9
|
FactoryGirl.create :album
|
11
10
|
end
|
11
|
+
|
12
|
+
(1..10).each do |sn|
|
13
|
+
FactoryGirl.create :track, album: nil
|
14
|
+
end
|
data/spec/factories/tracks.rb
CHANGED
data/spec/factories/traits.rb
CHANGED
@@ -28,12 +28,18 @@ describe Listings do
|
|
28
28
|
assert_parse_filter "album_name:'me 2' ", {album_name: "me 2"}, ""
|
29
29
|
|
30
30
|
assert_parse_filter "album_name:me-1", {album_name: "me-1"}, ""
|
31
|
+
|
32
|
+
assert_parse_filter_with_keys "project_id:3", [:id, :project_id], {project_id:"3"}, ""
|
31
33
|
end
|
32
34
|
|
33
35
|
def assert_parse_filter(text, hash, left_text)
|
36
|
+
assert_parse_filter_with_keys(text, hash.keys, hash, left_text)
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_parse_filter_with_keys(text, keys, hash, left_text)
|
34
40
|
listing = Listings::Base.new
|
35
41
|
|
36
|
-
filters, s = listing.parse_filter text,
|
42
|
+
filters, s = listing.parse_filter text, keys
|
37
43
|
|
38
44
|
s.should eq(left_text)
|
39
45
|
filters.should eq(hash)
|
data/spec/spec_helper.rb
CHANGED
@@ -4,7 +4,7 @@ require File.expand_path("../dummy/config/environment", __FILE__)
|
|
4
4
|
require 'rspec/rails'
|
5
5
|
require 'rspec/autorun'
|
6
6
|
require 'factory_girl_rails'
|
7
|
-
require File.expand_path("../../lib/rspec", __FILE__)
|
7
|
+
require File.expand_path("../../lib/listings/rspec", __FILE__)
|
8
8
|
|
9
9
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
10
10
|
# in spec/support/ and its subdirectories.
|
@@ -42,5 +42,4 @@ RSpec.configure do |config|
|
|
42
42
|
config.order = "random"
|
43
43
|
|
44
44
|
config.include FactoryGirl::Syntax::Methods
|
45
|
-
config.include RSpec::ListingsHelpers, type: :listing
|
46
45
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: listings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-06-
|
12
|
+
date: 2015-06-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -210,12 +210,16 @@ files:
|
|
210
210
|
- lib/listings/column_view.rb
|
211
211
|
- lib/listings/configuration.rb
|
212
212
|
- lib/listings/configuration_methods.rb
|
213
|
+
- lib/listings/custom_filter_descriptor.rb
|
214
|
+
- lib/listings/custom_filter_view.rb
|
213
215
|
- lib/listings/dynamic_binding.rb
|
214
216
|
- lib/listings/engine.rb
|
215
217
|
- lib/listings/filter_descriptor.rb
|
216
218
|
- lib/listings/filter_view.rb
|
217
219
|
- lib/listings/filters/base.rb
|
218
220
|
- lib/listings/kaminari_helpers_tag_patch.rb
|
221
|
+
- lib/listings/rspec/listings_helpers.rb
|
222
|
+
- lib/listings/rspec.rb
|
219
223
|
- lib/listings/scope_descriptor.rb
|
220
224
|
- lib/listings/sources/active_record_data_source.rb
|
221
225
|
- lib/listings/sources/data_source.rb
|
@@ -224,8 +228,6 @@ files:
|
|
224
228
|
- lib/listings/version.rb
|
225
229
|
- lib/listings/view_helper_methods.rb
|
226
230
|
- lib/listings.rb
|
227
|
-
- lib/rspec/listings_helpers.rb
|
228
|
-
- lib/rspec.rb
|
229
231
|
- lib/tasks/listings_tasks.rake
|
230
232
|
- LICENSE
|
231
233
|
- Rakefile
|
@@ -265,6 +267,7 @@ files:
|
|
265
267
|
- spec/dummy/config/environments/test.rb
|
266
268
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
267
269
|
- spec/dummy/config/initializers/inflections.rb
|
270
|
+
- spec/dummy/config/initializers/listings.rb
|
268
271
|
- spec/dummy/config/initializers/mime_types.rb
|
269
272
|
- spec/dummy/config/initializers/secret_token.rb
|
270
273
|
- spec/dummy/config/initializers/session_store.rb
|
@@ -313,18 +316,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
313
316
|
- - ! '>='
|
314
317
|
- !ruby/object:Gem::Version
|
315
318
|
version: '0'
|
316
|
-
segments:
|
317
|
-
- 0
|
318
|
-
hash: 3767681349647885791
|
319
319
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
320
320
|
none: false
|
321
321
|
requirements:
|
322
322
|
- - ! '>='
|
323
323
|
- !ruby/object:Gem::Version
|
324
324
|
version: '0'
|
325
|
-
segments:
|
326
|
-
- 0
|
327
|
-
hash: 3767681349647885791
|
328
325
|
requirements: []
|
329
326
|
rubyforge_project:
|
330
327
|
rubygems_version: 1.8.23.2
|
@@ -367,6 +364,7 @@ test_files:
|
|
367
364
|
- spec/dummy/config/environments/test.rb
|
368
365
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
369
366
|
- spec/dummy/config/initializers/inflections.rb
|
367
|
+
- spec/dummy/config/initializers/listings.rb
|
370
368
|
- spec/dummy/config/initializers/mime_types.rb
|
371
369
|
- spec/dummy/config/initializers/secret_token.rb
|
372
370
|
- spec/dummy/config/initializers/session_store.rb
|
data/lib/rspec.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "rspec/listings_helpers"
|