collate 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e6e9c829cf7d2ee33ab2a3dcc18976a0dd398ffe
4
- data.tar.gz: 4edbcc221115207821abe533c93a123a96bc9619
3
+ metadata.gz: c576c73f42f7ce0da453c0e0e0778a69fd9a27f7
4
+ data.tar.gz: 9db7728b9973c4bd4575b6a00f733d0312d69ed6
5
5
  SHA512:
6
- metadata.gz: 28caee2d1066e2e00c9b34d8dfe7fc2aa512a44d7c4db7fe862af92db92c5685c8a8e46b27c3b3308c46b5cdb49e4b51c2291c94e5dac432ce9399931fd9e41c
7
- data.tar.gz: ee77a8b8330258f9c034c944a729b005f9396741e7994bc8f7ae4f823e12a19e4f50ac8daba9f34d877071fc9b376402a3106efaff8d8641792d21bd708d6fef
6
+ metadata.gz: 64eb3c1bd01e5ffc31403424f1e3646bdb9e95a0fbb508bed7a1a3bca5a34e9e3f249cf39cb224565ebcb9e796c000d5a63a608210baf12631d4b40870b1f52b
7
+ data.tar.gz: 63b34d8658c421d24a87b125d818c9dd50c2bfb2285cfed011442cc4c486e01fcd712325215c874659644fd0ad2b071d16a81666cdb7444afacf00a11916b4b8
data/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  [![CircleCI](https://img.shields.io/circleci/project/github/trackingboard/collate.svg)](https://circleci.com/gh/trackingboard/collate)
4
4
  [![Coveralls](https://img.shields.io/coveralls/trackingboard/collate.svg)](https://coveralls.io/github/trackingboard/collate?branch=master)
5
- [![Gem](https://img.shields.io/gem/v/collate.svg)]()
6
- [![Gem](https://img.shields.io/gem/dt/collate.svg)]()
5
+ [![Gem](https://img.shields.io/gem/v/collate.svg)](https://rubygems.org/gems/collate)
6
+ [![Gem](https://img.shields.io/gem/dt/collate.svg)](https://rubygems.org/gems/collate)
7
7
 
8
8
  ## Installation
9
9
 
@@ -13,11 +13,11 @@ or with bundler in your Gemfile:
13
13
 
14
14
  ```gem 'collate'```
15
15
 
16
- ## Usage
16
+ ## Filter Usage
17
17
 
18
18
  This gem currently only supports PostgreSQL.
19
19
 
20
- To use collate in a model, include several collation definitions. The first argument is the name of the database column to use in the query. The simplest example looks like this:
20
+ To use collate filtering in a model, include several collation definitions. The first argument is the name of the database column to use in the query. The simplest example looks like this:
21
21
 
22
22
  ```
23
23
  class Person < ActiveRecord::Base
@@ -284,6 +284,129 @@ In order to use this in a view, you could have some HAML like this:
284
284
 
285
285
  This will ensure that the keys that the inputs are submitted with match the parameter key that the gem is expecting for that specific filter.
286
286
 
287
+ ## Sorting Usage
288
+
289
+ To use collate sorting for a model, include several ```collate_sort``` defintions. For example:
290
+
291
+ ```
292
+ class Person < ActiveRecord::Base
293
+ collate_sort :name
294
+ collate_sort :popularity
295
+ end
296
+ ```
297
+
298
+ Then, in the controller, use the ```collate``` method:
299
+
300
+ ```
301
+ @people = Person.collate(params)
302
+ ```
303
+
304
+ This will cause the people to be sorted on either ```name``` or ```popularity``` if the ```params[:order]``` value is set appropriately.
305
+
306
+ ```params[:order]``` must have a value of the format ```"#{table_name}.#{field_name} ASC``` or ```"#{table_name}.#{field_name} DESC```
307
+
308
+ For example:
309
+
310
+ ```
311
+ params[:order] = "people.name ASC"
312
+ @people = Person.collate(params)
313
+ ```
314
+
315
+ Will result in the following PostgreSQL query:
316
+
317
+ ```
318
+ SELECT * FROM people ORDER BY people.name ASC
319
+ ```
320
+
321
+ You can also pass parameter options to ```collate_sort``` for more complex sorting.
322
+
323
+ #### Default
324
+ --------------
325
+ ```
326
+ collate_sort :name, default: 'asc'
327
+ ```
328
+
329
+ This tells collate that this particular sorting should be performed if there is no other sorting specified by the user.
330
+
331
+ It is also the second sorting to be applied on top of another sort.
332
+
333
+ For instance:
334
+
335
+ ```
336
+ class Person < ActiveRecord::Base
337
+ collate_sort :name, default: 'desc'
338
+ collate_sort :popularity
339
+ end
340
+ ```
341
+
342
+ ```
343
+ params[:order] = 'people.popularity ASC'
344
+ @people = Person.collate(params)
345
+ ```
346
+
347
+ This would result in the following PostgreSQL query:
348
+
349
+ ```
350
+ ORDER BY people.popularity ASC, people.name DESC
351
+ ```
352
+
353
+ #### Joins
354
+ --------------
355
+ ```
356
+ collate_sort 'posts.created_at', joins: [:posts]
357
+ ```
358
+
359
+ This will perform the ActiveRecord joins before the sorting is applied. Doing this will allow you to sort on fields that are on related models.
360
+
361
+ #### Field_select
362
+ --------------
363
+ ```
364
+ collate_sort 'post_count', joins: [:posts], field_select: 'COUNT(posts.*) as post_count'
365
+ ```
366
+
367
+ This will perform the ActiveRecord select before the sorting is applied. Doing this will allow you to sort on fields created using a subquery.
368
+
369
+ #### Nulls_first
370
+ --------------
371
+ ```
372
+ collate_sort :popularity, nulls_first: true
373
+ ```
374
+
375
+ This will append ```NULLS FIRST``` to the order portion of the database query
376
+
377
+ #### Nulls_last
378
+ --------------
379
+ ```
380
+ collate_sort :popularity, nulls_last: true
381
+ ```
382
+
383
+ This will append ```NULLS LAST``` to the order portion of the database query
384
+
385
+ #### Label
386
+ --------------
387
+ ```
388
+ collate_sort :popularity, label: 'Popularity Score'
389
+ ```
390
+
391
+ This will modify the default sorting label, which is ```field.to_s.titleize```.
392
+
393
+ #### Asc_label
394
+ --------------
395
+ ```
396
+ collate_sort :popularity, asc_label: 'Popularity Score Lowest to Highest'
397
+ ```
398
+
399
+ This will modify the default ascending sorting label, which is ```#{label} ⬇```.
400
+
401
+ #### Desc_label
402
+ --------------
403
+ ```
404
+ collate_sort :popularity, desc_label: 'Popularity Score Highest to Lowest'
405
+ ```
406
+
407
+ This will modify the default descending sorting label, which is ```#{label} ⬆```.
408
+
409
+
287
410
  ## Contributing
288
411
 
289
412
  Bug reports and pull requests are welcome on GitHub at https://github.com/trackingboard/collate.
@@ -0,0 +1,9 @@
1
+ %select.collate_sort{opts}
2
+ - if opts[:allow_none]
3
+ %option{value: "", selected: (params[:order].to_s == "")}
4
+ None
5
+ - sorters.each do |sorter|
6
+ %option{value: "#{sorter.field} ASC", selected: (params[:order] == "#{sorter.field} ASC")}
7
+ = sorter.asc_label
8
+ %option{value: "#{sorter.field} DESC", selected: (params[:order] == "#{sorter.field} DESC")}
9
+ = sorter.desc_label
@@ -10,6 +10,14 @@ module Collate
10
10
  filters
11
11
  end
12
12
 
13
+ def sorting_for record, opts={}
14
+ sorters = record.model.collate_sorters ||= []
15
+
16
+ opts[:name] ||= "order"
17
+
18
+ render :partial => "collate/sort_select", locals: {sorters: sorters, opts: opts}
19
+ end
20
+
13
21
  def filter_for filter
14
22
  render :partial => "collate/#{filter.component[:type]}_field", locals: {filter: filter}
15
23
  end
@@ -1,8 +1,15 @@
1
1
  require_relative 'filter'
2
+ require_relative 'sorter'
2
3
 
3
4
  module Collate
4
5
  module ActiveRecordExtension
5
6
 
7
+ def collate_sort field, opts={}
8
+ initialize_collate
9
+
10
+ self.collate_sorters << Collate::Sorter.new(field, opts.merge({base_model_table_name: self.table_name}))
11
+ end
12
+
6
13
  def collate_on field, opts={}
7
14
  initialize_collate
8
15
 
@@ -33,6 +40,20 @@ module Collate
33
40
  end
34
41
  end
35
42
 
43
+ self.collate_sorters.each do |sorter|
44
+ sort_field, _, sort_direction = params[:order].to_s.partition(' ')
45
+
46
+ if(sort_field == sorter.field && ['ASC','DESC'].include?(sort_direction))
47
+ ar_rel = apply_sorter ar_rel, sorter, params[:order]
48
+ end
49
+ end
50
+
51
+ default_sort = self.collate_sorters.select { |s| s.default }.first
52
+ if default_sort.present?
53
+ ar_rel = apply_sorter ar_rel, default_sort, "#{default_sort.field} #{default_sort.default.upcase}", 'order'
54
+ params[:order] = "#{default_sort.field} #{default_sort.default.upcase}"
55
+ end
56
+
36
57
  ar_rel
37
58
  end
38
59
 
@@ -41,14 +62,37 @@ module Collate
41
62
  def initialize_collate
42
63
  if !self.method_defined? :collate_filters
43
64
  class << self
44
- attr_accessor :collate_filters, :default_group, :group_options
65
+ attr_accessor :collate_filters, :collate_sorters, :default_group, :group_options
45
66
  end
46
67
  end
47
68
  self.collate_filters ||= {}
69
+ self.collate_sorters ||= []
48
70
  self.default_group ||= :main
49
71
  self.group_options ||= {}
50
72
  end
51
73
 
74
+ def apply_sorter ar_rel, sorter, param_value, sorting_method = 'reorder'
75
+ if sorter.joins
76
+ sorter.joins.each do |join|
77
+ ar_rel = ar_rel.joins(join)
78
+ end
79
+ end
80
+
81
+ ar_rel = ar_rel.select("#{ar_rel.table_name}.*")
82
+
83
+ sorter.field_select = sorter.field unless sorter.field_select
84
+
85
+ ar_rel = ar_rel.select(sorter.field_select)
86
+
87
+ ar_rel = if sorter.nulls_first
88
+ ar_rel.send(sorting_method, "#{param_value} NULLS FIRST")
89
+ elsif sorter.nulls_last
90
+ ar_rel.send(sorting_method, "#{param_value} NULLS LAST")
91
+ else
92
+ ar_rel.send(sorting_method, param_value)
93
+ end
94
+ end
95
+
52
96
  def apply_filter ar_rel, filter, param_value
53
97
  filter_value = if param_value.duplicable?
54
98
  param_value.dup
@@ -0,0 +1,23 @@
1
+ module Collate
2
+ class Sorter
3
+ attr_accessor :field, :base_model_table_name, :label, :asc_label, :desc_label,
4
+ :field_select, :joins, :default, :nulls_last, :nulls_first
5
+
6
+ def initialize(field, opt={})
7
+ opt.each do |field, value|
8
+ self.send("#{field}=", value)
9
+ end
10
+
11
+ self.field = field
12
+
13
+ self.label ||= self.field.to_s.titleize
14
+ self.asc_label ||= "#{label} ⬇"
15
+ self.desc_label ||= "#{label} ⬆"
16
+
17
+ self.field = "#{base_model_table_name}.#{field}" if field.is_a? Symbol
18
+
19
+ self.joins ||= []
20
+ end
21
+
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Collate
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: collate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Page
@@ -176,12 +176,14 @@ files:
176
176
  - lib/app/views/collate/_checkboxgroup_field.html.haml
177
177
  - lib/app/views/collate/_date_field.html.haml
178
178
  - lib/app/views/collate/_select_field.html.haml
179
+ - lib/app/views/collate/_sort_select.html.haml
179
180
  - lib/app/views/collate/_string_field.html.haml
180
181
  - lib/collate.rb
181
182
  - lib/collate/action_view_extension.rb
182
183
  - lib/collate/active_record_extension.rb
183
184
  - lib/collate/engine.rb
184
185
  - lib/collate/filter.rb
186
+ - lib/collate/sorter.rb
185
187
  - lib/collate/version.rb
186
188
  homepage: https://github.com/trackingboard/collate
187
189
  licenses: