effective_datatables 3.1.0 → 3.1.1

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