effective_datatables 3.1.0 → 3.1.1

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: ed64f666d0e25311df8bd6d261f91561ff5a4b06
4
- data.tar.gz: 80cbfdb2f683497fdbfff4f373068ee254fefb69
3
+ metadata.gz: 1a2b9ae410c6e532a465c32336482e9970f13e53
4
+ data.tar.gz: 368a0929e034ef902d2a0bde8eb3a7748c49929b
5
5
  SHA512:
6
- metadata.gz: c5f12a41603c30fdbaea17b0eabcdf801baada748aca0b020e0d570911389b599fb1c10a1b09b4b5a4cfa77346c85c70940435ddf7cac64d567c786c2336f2be
7
- data.tar.gz: 149fcbcf5c3e48bf996db130b649b84acbfceac7f77b47a34a2db90e76c4228bedf96e9e9db6f96ace6826a17695c64c3ad0246942b5b2edd3a7d614b0211a9c
6
+ metadata.gz: d013b3eabb65c821560fe91db66f8cdbb7b1c07671fa7b973d2bd57cf51a9f31d98190955e659a7b492b8b9237af1ebffccbd846e9b4b71e60c553267dbf2105
7
+ data.tar.gz: b76751d9fe31c78f7e0d4fc54bbd8878d46efd2a070216216e157841dbad951aec9aa1996a0dcc58dd345b406189dfe6026d675cd130aa5b4af9d88d253fda49
data/README.md CHANGED
@@ -136,7 +136,7 @@ class PostsDatatable < Effective::Datatable
136
136
  # It has access to the attributes and filters Hashes, representing the current state
137
137
  # It must return an ActiveRecord::Relation or an Array of Arrays
138
138
  collection do
139
- scope = Post.all.where(created_at: filters[:start_date]...filters[:end_date])
139
+ scope = Post.all.joins(:user).where(created_at: filters[:start_date]...filters[:end_date])
140
140
  scope = scope.where(user_id: attributes[:user_id]) if attributes[:user_id]
141
141
  scope
142
142
  end
@@ -209,6 +209,8 @@ class PostsDatatable < Effective::Datatable
209
209
 
210
210
  if attributes[:user_id].nil? # Show all users, otherwise this table is meant for one user only
211
211
  col :user, search: { collection: User.authors }
212
+
213
+ col 'user.first_name' # Using the joined syntax
212
214
  end
213
215
 
214
216
  if can?(:index, Comment)
@@ -484,6 +486,14 @@ end
484
486
 
485
487
  You can also set custom search and sort on a per-column basis. See Advanced Search and Sort below.
486
488
 
489
+ If the column name matches a `belongs_to`, `has_many` or other association on your collection class, like `col :user`, the column will be created as a resource column.
490
+
491
+ A resource column will try to link to the show/edit/destroy actions of its objects, based on permissions and routes. You can alter this behaviour with the `action:` variable.
492
+
493
+ You can also use the joined syntax, `col 'user.email'` to create a column for just this one field.
494
+
495
+ This feature is only working with `belongs_to` and you need to add the `.joins(:user)` to the collection do ... end block yourself.
496
+
487
497
  ### val
488
498
 
489
499
  Shorthand for value, this command also creates a column on the datatable.
@@ -14,7 +14,8 @@ module Effective
14
14
  rescue => e
15
15
  (EffectiveDatatables.authorized?(self, :index, @datatable.try(:collection_class)) rescue false)
16
16
 
17
- render json: error_json(message: e.message)
17
+ render json: error_json(e)
18
+ raise e
18
19
  end
19
20
  end
20
21
 
@@ -25,11 +26,11 @@ module Effective
25
26
  id.classify.safe_constantize || id.classify.pluralize.safe_constantize
26
27
  end
27
28
 
28
- def error_json(message:)
29
+ def error_json(e)
29
30
  {
30
31
  data: [],
31
32
  draw: params[:draw].to_i,
32
- effective_datatables_error: message.presence || 'unknown error',
33
+ effective_datatables_error: (e.message.presence unless e.class.name.include?('ActiveRecord::')) || 'unexpected operation',
33
34
  recordsTotal: 0,
34
35
  recordsFiltered: 0,
35
36
  aggregates: [],
@@ -60,10 +60,23 @@ module Effective
60
60
  columns.map do |name, opts|
61
61
  if state[:visible][name] == false && (name != order_name) # Sort by invisible array column
62
62
  BLANK
63
- elsif opts[:partial] || (opts[:format] && !opts[:compute])
63
+ elsif opts[:partial]
64
64
  active_record_collection? ? obj : obj[opts[:index]]
65
65
  elsif opts[:compute]
66
66
  dsl_tool.instance_exec(obj, (active_record_collection? ? collection : obj[opts[:index]]), &opts[:compute])
67
+ elsif opts[:format]
68
+ active_record_collection? ? obj : obj[opts[:index]]
69
+ elsif opts[:resource]
70
+ resource = active_record_collection? ? obj : obj[opts[:index]]
71
+
72
+ if opts[:resource_field]
73
+ (associated, field) = name.to_s.split('.').first(2)
74
+ values = Array(resource.send(associated)).map { |obj| obj.send(field) }.flatten.compact
75
+ values.length == 1 ? values.first : values
76
+ else
77
+ value.send(name)
78
+ end
79
+
67
80
  elsif opts[:as] == :effective_obfuscation
68
81
  obj.to_param
69
82
  elsif array_collection?
@@ -22,15 +22,17 @@ module Effective
22
22
  def col(name, action: nil, as: nil, col_class: nil, label: nil, partial: nil, partial_as: nil, responsive: 10000, search: {}, sort: true, sql_column: nil, th: nil, th_append: nil, visible: true, &format)
23
23
  raise 'You cannot use partial: ... with the block syntax' if partial && block_given?
24
24
 
25
- datatable._columns[name.to_sym] = Effective::DatatableColumn.new(
25
+ name = name.to_sym unless name.to_s.include?('.')
26
+
27
+ datatable._columns[name] = Effective::DatatableColumn.new(
26
28
  action: action, # resource columns only
27
29
  as: as,
28
30
  compute: nil,
29
31
  col_class: col_class,
30
32
  format: (format if block_given?),
31
33
  index: datatable.columns.length,
32
- label: label || name.to_s.titleize,
33
- name: name.to_sym,
34
+ label: label || name.to_s.split('.').last.titleize,
35
+ name: name,
34
36
  partial: partial,
35
37
  partial_as: partial_as,
36
38
  responsive: responsive,
@@ -48,15 +50,17 @@ module Effective
48
50
  def val(name, action: nil, as: nil, col_class: nil, label: nil, partial: nil, partial_as: nil, responsive: 10000, search: {}, sort: true, sql_column: false, th: nil, th_append: nil, visible: true, &compute)
49
51
  raise 'You cannot use partial: ... with the block syntax' if partial && block_given?
50
52
 
51
- datatable._columns[name.to_sym] = Effective::DatatableColumn.new(
53
+ name = name.to_sym unless name.to_s.include?('.')
54
+
55
+ datatable._columns[name] = Effective::DatatableColumn.new(
52
56
  action: action, # Resource columns only
53
57
  as: as,
54
58
  compute: (compute if block_given?),
55
59
  col_class: col_class,
56
60
  format: nil,
57
61
  index: datatable.columns.length,
58
- label: label || name.to_s.titleize,
59
- name: name.to_sym,
62
+ label: label || name.to_s.split('.').last.titleize,
63
+ name: name,
60
64
  partial: partial,
61
65
  partial_as: partial_as,
62
66
  responsive: responsive,
@@ -18,12 +18,42 @@ module Effective
18
18
 
19
19
  if active_record_collection?
20
20
  columns.each do |name, opts|
21
+
22
+ if name.kind_of?(String) && name.include?('.')
23
+ raise "invalid datatables column '#{name}'. the joined syntax only supports one dot." if name.scan(/\./).count > 1
24
+
25
+ (associated, field) = name.split('.').first(2)
26
+
27
+ unless resource.macros.include?(resource.sql_type(associated))
28
+ raise "invalid datatables column '#{name}'. unable to find '#{name.split('.').first}' association on '#{resource}'."
29
+ end
30
+
31
+ unless collection.joined_includes_values.include?(associated) || collection.joined_includes_values.include?(associated.to_sym)
32
+ raise "your datatables collection must .joins(:#{associated}) to work with the joined syntax"
33
+ end
34
+
35
+ opts[:resource] = Effective::Resource.new(resource.associated(associated), namespace: controller_namespace)
36
+
37
+ if opts[:resource].column(field)
38
+ opts[:as] ||= opts[:resource].sql_type(field)
39
+ opts[:sql_column] = opts[:resource].sql_column(field) if opts[:sql_column].nil?
40
+
41
+ opts[:resource].sort_column = field
42
+ opts[:resource].search_columns = field
43
+ end
44
+
45
+ opts[:resource_field] = field
46
+
47
+ next
48
+ end
49
+
50
+ # Regular fields
21
51
  opts[:as] ||= resource.sql_type(name)
22
52
  opts[:sql_column] = resource.sql_column(name) if opts[:sql_column].nil?
23
53
 
24
54
  case opts[:as]
25
55
  when *resource.macros
26
- opts[:resource] = Effective::Resource.new(resource.associated(name), namespace: controller_namespace)
56
+ opts[:resource] ||= Effective::Resource.new(resource.associated(name), namespace: controller_namespace)
27
57
  (opts[:sql_column] = name) if opts[:sql_column].nil?
28
58
  when Class
29
59
  if opts[:as].ancestors.include?(ActiveRecord::Base)
@@ -63,9 +93,11 @@ module Effective
63
93
 
64
94
  columns.each do |name, opts|
65
95
  opts[:as] ||= :string
66
- opts[:as] = :email if (opts[:as] == :string && name == :email)
96
+ opts[:as] = :email if (opts[:as] == :string && name.to_s.end_with?('email'))
67
97
 
68
- opts[:partial] ||= '/effective/datatables/resource_column' if (opts[:resource] && opts[:as] != :effective_addresses)
98
+ if opts[:resource] && !opts[:resource_field] && opts[:as] != :effective_addresses
99
+ opts[:partial] ||= '/effective/datatables/resource_column'
100
+ end
69
101
 
70
102
  opts[:col_class] = "col-#{opts[:as]} col-#{name.to_s.parameterize} #{opts[:col_class]}".strip
71
103
  end
@@ -113,7 +113,7 @@ module Effective
113
113
  state[:visible] = {}
114
114
 
115
115
  params[:columns].values.each do |params|
116
- name = params[:name].to_sym
116
+ name = (params[:name].include?('.') ? params[:name] : params[:name].to_sym)
117
117
 
118
118
  if params[:search][:value].present? && !['null'].include?(params[:search][:value])
119
119
  state[:search][name] = params[:search][:value]
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '3.1.0'.freeze
2
+ VERSION = '3.1.1'.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: 3.1.0
4
+ version: 3.1.1
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: 2017-07-12 00:00:00.000000000 Z
11
+ date: 2017-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails