effective_datatables 1.8.2 → 1.8.3

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: f1e69441faaaf97e4d7233349e3251117d31557d
4
- data.tar.gz: e3fbf33bb81f9f037ba8bb8dfbf618f97a0b96c5
3
+ metadata.gz: 51442e1874c5619504602bba266af6ebdd589a2a
4
+ data.tar.gz: 51f2e7929b20e801d9b6b30b70fd4c0c028503d6
5
5
  SHA512:
6
- metadata.gz: 0719337d5baaa89aecd3abf33c4f5f85f8e31d07abf1b15b486ff10d560efedeafd191464fd06949035a611b165659b9c8216bc7c160e57ae04b7dc0c6502a82
7
- data.tar.gz: 2e2e94e71e14e63c0fa12ca3c10858e2c8d2b9d907ef5ee506fed6fd8c71b4218f3287ff519e0de8db37884d33d9c8a1574b61df1fba60e79dd94b70aa9ca17d
6
+ metadata.gz: 06f07d33e9eaf67ea873f21650b505338e1928a31ce5138264aa5eed6cb1715b8c84c0916a2ea2c7ba0d08443e22cbd0c6acbaf4a9bcfde8cfa1bc320b09d166
7
+ data.tar.gz: 055b33ce39c9b1745c74f73d105f4d16134e0bdea5c1e5e7587ccda73bbfa815826499c8166a3144b2f9acc548718df71117af048bac4b56f99a042162c42e90
data/README.md CHANGED
@@ -201,12 +201,46 @@ def query_total
201
201
  end
202
202
  ```
203
203
 
204
+ ### Array Backed collection
205
+
206
+ Don't want to use ActiveRecord? Not a problem.
207
+
208
+ Define your collection as an Array of Arrays, declare only array_columns, and everything works as expected.
209
+
210
+ ```ruby
211
+ module Effective
212
+ module Datatables
213
+ class ArrayBackedDataTable < Effective::Datatable
214
+ array_column :id
215
+ array_column :first_name
216
+ array_column :last_name
217
+ array_column :email
218
+
219
+ def collection
220
+ [
221
+ [1, 'Dana', 'Janssen', 'dana@agilestyle.com'],
222
+ [2, 'Ashley', 'Janssen', 'ashley@agilestyle.com'],
223
+ [3, 'Matthew', 'Riemer', 'matthew@agilestyle.com'],
224
+ [4, 'Stephen', 'Brown', 'stephen@agilestyle.com'],
225
+ [5, 'Warren', 'Uhrich', 'warren@agilestyle.com'],
226
+ [6, 'Dallas', 'Meidinger', 'dallas@agilestyle.com'],
227
+ [7, 'Nathan', 'Feaver', 'nathan@agilestyle.com']
228
+ ]
229
+ end
230
+
231
+ end
232
+ end
233
+ end
234
+ ```
235
+
204
236
  ## table_column
205
237
 
206
238
  This is the main DSL method that you will interact with.
207
239
 
208
240
  table_column defines a 1:1 mapping between a SQL database table column and a frontend jQuery Datatables table column. It creates a column.
209
241
 
242
+ table_column performs searching and sorting on the raw database records, before any results are rendered.
243
+
210
244
  Options may be passed to specify the display, search, sort and filter behaviour for that column.
211
245
 
212
246
  When the given name of the table_column matches an ActiveRecord attribute, the options are set intelligently based on the underlying datatype.
@@ -239,7 +273,24 @@ table_column :user_id, :if => Proc.new { attributes[:user_id].blank? }, :filter
239
273
  end
240
274
  ```
241
275
 
242
- All table_columns are `:visible => true`, `:sortable => true` by default.
276
+ All table_columns are `visible: true`, `sortable: true` by default.
277
+
278
+ ## array_column
279
+
280
+ `array_column` accepts the same options as `table_column` and behaves identically on the frontend.
281
+
282
+ The difference occurs with sorting and filtering:
283
+
284
+ array_columns perform searching and sorting on the computed results after all columns have been rendered.
285
+
286
+ With a `table_column`, the frontend sends some search terms to the server, the raw database table is searched & sorted using standard ActiveRecord .where(), the appropriate rows returned, and then each row is rendered as per the rendering options.
287
+
288
+ With an `array_column`, the front end sends some search terms to the server, all rows are returned and rendered, and then the rendered output is searched & sorted.
289
+
290
+ This allows the output of an `array_column` to be anything complex that cannot be easily computed from the database.
291
+
292
+ When searching & sorting with a mix of table_columns and array_columns, all the table_columns are processed first so the most work is put on the database, the least on rails.
293
+
243
294
 
244
295
  ### General Options
245
296
 
@@ -351,7 +402,7 @@ The request object is available to the table_column, so you could just as easily
351
402
  request.referer.include?('/admin/')
352
403
  ```
353
404
 
354
- ### Header Rendering
405
+ ### Column Header Rendering Options
355
406
 
356
407
  You can override the default rendering and define a partial to use for the header `<th>`:
357
408
 
@@ -376,21 +427,6 @@ Quickly create multiple table_columns all with default options:
376
427
  table_columns :id, :created_at, :updated_at, :category, :title
377
428
  ```
378
429
 
379
- ## array_column
380
-
381
- `array_column` accepts the same options as `table_column` and behaves identically on the frontend.
382
-
383
- The difference occurs with sorting and filtering:
384
-
385
- With a `table_column`, the frontend sends some search terms to the server, the raw database table is searched & sorted using standard ActiveRecord .where(), the appropriate rows returned, and then each row is rendered as per the rendering options.
386
-
387
- With an `array_column`, the front end sends some search terms to the server, all rows are returned and rendered, and then the rendered output is searched & sorted.
388
-
389
- This allows the output of an `array_column` to be anything complex that cannot be easily computed from the database.
390
-
391
- When searching & sorting with a mix of table_columns and array_columns, all the table_columns are processed first so the most work is put on the database, the least on rails.
392
-
393
-
394
430
  ## default_order
395
431
 
396
432
  Sort the table by this field and direction on start up
@@ -414,43 +450,11 @@ Valid options are `10, 25, 50, 100, 250, 1000, :all`
414
450
 
415
451
  There are a few other ways to customize the behaviour of effective_datatables
416
452
 
417
- ### Display of an Empty Datatable
418
-
419
- How an empty datatable (0 display records) is displayed depends on how `render_datatable` is called.
420
-
421
- To render the full datatable with the default 'No data available in table' message:
422
-
423
- ```haml
424
- = render_datatable(@datatable)
425
- ```
426
-
427
- To skip rendering the datatable and just output a custom message:
428
-
429
- ```haml
430
- = render_datatable(@datatable, 'There are no posts.')
431
- ```
432
-
433
- or
434
-
435
- ```haml
436
- = render_datatable(@datatable, :empty => 'There are no posts.')
437
- ```
438
-
439
- To skip rendering the datatable and instead render given content:
440
-
441
- ```haml
442
- = render_datatable(@datatable) do
443
- %p There are no posts.
444
- %p
445
- Have a picture of a cat instead
446
- = image_tag('cat.png')
447
- ```
448
-
449
453
  ### Checking for Empty collection
450
454
 
451
- While the 'what to render when empty' situation is handled by the above syntax, you may still check whether the datatable has records to display by calling `@datatable.empty?` and `@datatable.present?`.
455
+ Check whether the datatable has records by calling `@datatable.empty?` and `@datatable.present?`.
452
456
 
453
- Keep in mind, these methods look at the collection's total records, rather than the display/filtered records.
457
+ Keep in mind, these methods look at the collection's total records, not the currently displayed/filtered records.
454
458
 
455
459
 
456
460
  ### Customize Filter Behaviour
@@ -566,37 +570,28 @@ module Effective
566
570
  end
567
571
  ```
568
572
 
569
- ## Array Backed collection
573
+ ## Working with other effective_gems
570
574
 
571
- Don't want to use ActiveRecord? Not a problem.
575
+ ### Effective Obfuscation
572
576
 
573
- Define your collection as an Array of Arrays, declare only array_columns, and everything works as expected.
577
+ When working with an ActiveRecord collection that implements [effective_obfuscation](https://github.com/code-and-effect/effective_obfuscation) for the ID column,
578
+ that column's filters and sorting will be automatically configured.
574
579
 
575
- ```ruby
576
- module Effective
577
- module Datatables
578
- class ArrayBackedDataTable < Effective::Datatable
579
- array_column :id
580
- array_column :first_name
581
- array_column :last_name
582
- array_column :email
580
+ Just define `table_column :id`.
583
581
 
584
- def collection
585
- [
586
- [1, 'Dana', 'Janssen', 'dana@agilestyle.com'],
587
- [2, 'Ashley', 'Janssen', 'ashley@agilestyle.com'],
588
- [3, 'Matthew', 'Riemer', 'matthew@agilestyle.com'],
589
- [4, 'Stephen', 'Brown', 'stephen@agilestyle.com'],
590
- [5, 'Warren', 'Uhrich', 'warren@agilestyle.com'],
591
- [6, 'Dallas', 'Meidinger', 'dallas@agilestyle.com'],
592
- [7, 'Nathan', 'Feaver', 'nathan@agilestyle.com']
593
- ]
594
- end
582
+ Unfortunately, due to the effective_obfuscation algorithm, sorting and filtering by partial values is not supported.
583
+
584
+ So the column may not be sorted, and may only be filtered by typing the entire 10-digit number, with or without any formatting.
585
+
586
+ ### Effective Roles
587
+
588
+ When working with an ActiveRecord collection that implements [effective_roles](https://github.com/code-and-effect/effective_roles),
589
+ the filters and sorting will be automatically configured.
590
+
591
+ Just define `table_column :roles`.
592
+
593
+ The `EffectiveRoles.roles` collection will be used for the filter values, and sorting will be done by roles_mask.
595
594
 
596
- end
597
- end
598
- end
599
- ```
600
595
 
601
596
  ## Get access to the raw results
602
597
 
@@ -42,9 +42,9 @@ module Effective
42
42
  case table_column[:type]
43
43
  when :string, :text
44
44
  if table_column[:filter][:type] == :select && table_column[:filter][:fuzzy] != true
45
- collection.where("#{column} = :term", :term => term)
45
+ collection.where("#{column} = :term", term: term)
46
46
  else
47
- collection.where("#{column} ILIKE :term", :term => "%#{term}%")
47
+ collection.where("#{column} ILIKE :term", term: "%#{term}%")
48
48
  end
49
49
  when :datetime
50
50
  begin
@@ -68,22 +68,24 @@ module Effective
68
68
  end_at = start_at
69
69
  end
70
70
 
71
- collection.where("#{column} >= :start_at AND #{column} <= :end_at", :start_at => start_at, :end_at => end_at)
71
+ collection.where("#{column} >= :start_at AND #{column} <= :end_at", start_at: start_at, end_at: end_at)
72
72
  rescue => e
73
73
  collection
74
74
  end
75
75
  when :obfuscated_id
76
76
  if (deobfuscated_id = collection.deobfuscate(term)) == term # We weren't able to deobfuscate it, so this is an Invalid ID
77
- collection.where("#{column} = :term", :term => 0)
77
+ collection.where("#{column} = :term", term: 0)
78
78
  else
79
- collection.where("#{column} = :term", :term => deobfuscated_id)
79
+ collection.where("#{column} = :term", term: deobfuscated_id)
80
80
  end
81
+ when :effective_roles
82
+ collection.with_role(term)
81
83
  when :integer
82
- collection.where("#{column} = :term", :term => term.to_i)
84
+ collection.where("#{column} = :term", term: term.to_i)
83
85
  when :year
84
- collection.where("EXTRACT(YEAR FROM #{column}) = :term", :term => term.to_i)
86
+ collection.where("EXTRACT(YEAR FROM #{column}) = :term", term: term.to_i)
85
87
  else
86
- collection.where("#{column} = :term", :term => term)
88
+ collection.where("#{column} = :term", term: term)
87
89
  end
88
90
  end
89
91
 
@@ -355,6 +355,8 @@ module Effective
355
355
  val = (obj.send(name) rescue nil).to_s
356
356
  elsif opts[:type] == :obfuscated_id
357
357
  (obj.send(:to_param) rescue nil).to_s
358
+ elsif opts[:type] == :effective_roles
359
+ (obj.send(:roles) rescue []).join(', ')
358
360
  else
359
361
  val = (obj.send(name) rescue nil)
360
362
  val = (obj[opts[:array_index]] rescue nil) if val == nil
@@ -365,9 +367,7 @@ module Effective
365
367
  case value
366
368
  when Date
367
369
  value.strftime(EffectiveDatatables.date_format)
368
- when Time
369
- value.strftime(EffectiveDatatables.datetime_format)
370
- when DateTime
370
+ when Time, DateTime
371
371
  value.strftime(EffectiveDatatables.datetime_format)
372
372
  else
373
373
  value.to_s
@@ -429,7 +429,7 @@ module Effective
429
429
  cols.each_with_index do |(name, _), index|
430
430
  # If this is a belongs_to, add an :if clause specifying a collection scope if
431
431
  if belong_tos.key?(name)
432
- cols[name][:if] ||= Proc.new { attributes[belong_tos[name][:foreign_key]].blank? } # :if => Proc.new { attributes[:user_id].blank? }
432
+ cols[name][:if] ||= Proc.new { attributes[belong_tos[name][:foreign_key]].blank? }
433
433
  end
434
434
 
435
435
  sql_column = (collection.columns rescue []).find do |column|
@@ -443,14 +443,22 @@ module Effective
443
443
  cols[name][:column] ||= (sql_table && sql_column) ? "\"#{sql_table.name}\".\"#{sql_column.name}\"" : name
444
444
  cols[name][:width] ||= nil
445
445
  cols[name][:sortable] = true if cols[name][:sortable] == nil
446
- cols[name][:type] ||= (belong_tos.key?(name) ? :belongs_to : (sql_column.try(:type).presence || :string))
446
+ cols[name][:type] ||= (belong_tos.key?(name) ? :belongs_to : sql_column.try(:type).presence) || :string
447
447
  cols[name][:class] = "col-#{cols[name][:type]} col-#{name} #{cols[name][:class]}".strip
448
448
 
449
- if name == 'id' && collection.respond_to?(:deobfuscate)
449
+ # EffectiveObfuscation
450
+ if name == 'id' && defined?(EffectiveObfuscation) && collection.respond_to?(:deobfuscate)
450
451
  cols[name][:sortable] = false
451
452
  cols[name][:type] = :obfuscated_id
452
453
  end
453
454
 
455
+ # EffectiveRoles, if you do table_column :roles, everything just works
456
+ if name == 'roles' && defined?(EffectiveRoles) && collection.respond_to?(:with_role)
457
+ cols[name][:sortable] = true
458
+ cols[name][:column] = sql_table.present? ? "\"#{sql_table.name}\".\"roles_mask\"" : name
459
+ cols[name][:type] = :effective_roles
460
+ end
461
+
454
462
  if sql_table.present? && sql_column.blank? # This is a SELECT AS column
455
463
  cols[name][:sql_as_column] = true
456
464
  end
@@ -464,38 +472,29 @@ module Effective
464
472
  end
465
473
 
466
474
  def initialize_table_column_filter(filter, col_type, belongs_to)
467
- return {:type => :null} if filter == false
468
-
469
- if filter.kind_of?(Symbol)
470
- filter = HashWithIndifferentAccess.new(:type => filter)
471
- elsif filter.kind_of?(String)
472
- filter = HashWithIndifferentAccess.new(:type => filter.to_sym)
473
- elsif filter.kind_of?(Hash) == false
474
- filter = HashWithIndifferentAccess.new()
475
- end
475
+ return {type: :null} if filter == false
476
+
477
+ filter = {type: filter.to_sym} if filter.kind_of?(String)
478
+ filter = {} unless filter.kind_of?(Hash)
476
479
 
477
480
  # This is a fix for passing filter[:selected] == false, it needs to be 'false'
478
481
  filter[:selected] = filter[:selected].to_s unless filter[:selected].nil?
479
482
 
480
- filter = case col_type
483
+ case col_type
481
484
  when :belongs_to
482
- HashWithIndifferentAccess.new(
483
- :type => :select,
484
- :values => Proc.new { belongs_to[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[1] <=> y[1] } }
485
- ).merge(filter)
485
+ {
486
+ type: :select,
487
+ values: Proc.new { belongs_to[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[1] <=> y[1] } }
488
+ }
489
+ when :effective_roles
490
+ {type: :select, values: EffectiveRoles.roles}
486
491
  when :integer
487
- HashWithIndifferentAccess.new(:type => :number).merge(filter)
492
+ {type: :number}
488
493
  when :boolean
489
- HashWithIndifferentAccess.new(:type => :boolean, :values => [true, false]).merge(filter)
494
+ {type: :boolean, values: [true, false]}
490
495
  else
491
- HashWithIndifferentAccess.new(:type => :string).merge(filter)
492
- end
493
-
494
- if filter[:type] == :boolean
495
- filter = HashWithIndifferentAccess.new(:values => [true, false]).merge(filter)
496
- end
497
-
498
- filter
496
+ {type: :string}
497
+ end.merge(filter.symbolize_keys)
499
498
  end
500
499
 
501
500
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '1.8.2'.freeze
2
+ VERSION = '1.8.3'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_datatables
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.2
4
+ version: 1.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-30 00:00:00.000000000 Z
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails