effective_datatables 1.8.2 → 1.8.3

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: 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