Class: Effective::Datatable

Inherits:
Object
  • Object
show all
Defined in:
app/models/effective/datatable.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Datatable

Returns a new instance of Datatable.



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/models/effective/datatable.rb', line 72

def initialize(*args)
  unless active_record_collection? || (collection.kind_of?(Array) && collection.first.kind_of?(Array))
    raise "Unsupported collection type. Should be ActiveRecord class, ActiveRecord relation, or an Array of Arrays [[1, 'something'], [2, 'something else']]"
  end

  if args.present?
    raise 'Effective::Datatable.new() can only be called with a Hash like arguments' unless args.first.kind_of?(Hash)
    args.first.each { |k, v| self.attributes[k] = v }
  end

  # Any pre-selected search terms should be assigned now
  search_terms.each { |column, term| self.send("#{column}=", term) }
end

Instance Attribute Details

#attributesObject

Any attributes set on initialize will be echoed back and available to the class



87
88
89
# File 'app/models/effective/datatable.rb', line 87

def attributes
  @attributes
end

#display_recordsObject

Returns the value of attribute display_records.



3
4
5
# File 'app/models/effective/datatable.rb', line 3

def display_records
  @display_records
end

#total_recordsObject

Returns the value of attribute total_records.



3
4
5
# File 'app/models/effective/datatable.rb', line 3

def total_records
  @total_records
end

#viewObject

Returns the value of attribute view.



3
4
5
# File 'app/models/effective/datatable.rb', line 3

def view
  @view
end

Class Method Details

.actions_column(options = {}, proc = nil, &block) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/models/effective/datatable.rb', line 37

def actions_column(options = {}, proc = nil, &block)
  show = options.fetch(:show, false)
  edit = options.fetch(:edit, true)
  destroy = options.fetch(:destroy, true)
  name = options.fetch(:name, 'actions')

  opts = {
    sortable: false,
    filter: false,
    partial: '/effective/datatables/actions_column',
    partial_local: :resource,
    partial_locals: { show_action: show, edit_action: edit, destroy_action: destroy }
  }

  table_column(name, opts, proc, &block)
end

.allObject



8
9
10
# File 'app/models/effective/datatable.rb', line 8

def all
  EffectiveDatatables.datatables.map { |klass| klass.new() }
end

.array_column(name, options = {}, proc = nil, &block) ⇒ Object



33
34
35
# File 'app/models/effective/datatable.rb', line 33

def array_column(name, options = {}, proc = nil, &block)
  table_column(name, options.merge!({:array_column => true}), proc, &block)
end

.array_columns(*names) ⇒ Object



54
55
56
# File 'app/models/effective/datatable.rb', line 54

def array_columns(*names)
  names.each { |name| array_column(name) }
end

.default_entries(entries) ⇒ Object



62
63
64
# File 'app/models/effective/datatable.rb', line 62

def default_entries(entries)
  @default_entries = entries
end

.default_order(name, direction = :asc) ⇒ Object



58
59
60
# File 'app/models/effective/datatable.rb', line 58

def default_order(name, direction = :asc)
  @default_order = {name => direction}
end

.find(obj, attributes = nil) ⇒ Object



12
13
14
15
# File 'app/models/effective/datatable.rb', line 12

def find(obj, attributes = nil)
  obj = obj.respond_to?(:to_param) ? obj.to_param : obj
  EffectiveDatatables.datatables.find { |klass| klass.name.underscore.parameterize == obj }.try(:new, attributes.presence || {})
end

.model_nameObject

Searching & Filters



66
67
68
# File 'app/models/effective/datatable.rb', line 66

def model_name # Searching & Filters
  @model_name ||= ActiveModel::Name.new(self)
end

.table_column(name, options = {}, proc = nil, &block) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
# File 'app/models/effective/datatable.rb', line 17

def table_column(name, options = {}, proc = nil, &block)
  if block_given?
    raise "You cannot use :partial => '' with the block syntax" if options[:partial]
    raise "You cannot use :proc => ... with the block syntax" if options[:proc]
    options[:block] = block
  end
  raise "You cannot use both :partial => '' and proc => ..." if options[:partial] && options[:proc]

  send(:attr_accessor, name)
  (@table_columns ||= HashWithIndifferentAccess.new())[name] = options
end

.table_columns(*names) ⇒ Object



29
30
31
# File 'app/models/effective/datatable.rb', line 29

def table_columns(*names)
  names.each { |name| table_column(name) }
end

Instance Method Details

#collectionObject



102
103
104
# File 'app/models/effective/datatable.rb', line 102

def collection
  raise "You must define a collection. Something like an ActiveRecord User.all or an Array of Arrays [[1, 'something'], [2, 'something else']]"
end

#collection_classObject



106
107
108
# File 'app/models/effective/datatable.rb', line 106

def collection_class
  collection.respond_to?(:klass) ? collection.klass : self.class
end

#default_entriesObject



178
179
180
181
182
183
184
# File 'app/models/effective/datatable.rb', line 178

def default_entries
  @default_entries ||= begin
    entries = (self.class.instance_variable_get(:@default_entries).presence || EffectiveDatatables.default_entries)
    entries = -1 if entries.to_s.downcase == 'all'
    [10, 25, 50, 100, 250, 1000, -1].include?(entries) ? entries : 25
  end
end

#default_orderObject



174
175
176
# File 'app/models/effective/datatable.rb', line 174

def default_order
  self.class.instance_variable_get(:@default_order)
end

#display_table_columnsObject

This is for the ColReorder plugin It sends us a list of columns that are different than our table_columns order So this method just returns an array of column names, as per ColReorder



124
125
126
127
128
129
130
131
132
# File 'app/models/effective/datatable.rb', line 124

def display_table_columns
  if params[:columns].present?
    HashWithIndifferentAccess.new().tap do |display_columns|
      params[:columns].each do |_, values|
        display_columns[values[:name]] = table_columns[values[:name]]
      end
    end
  end
end

#empty?Boolean

Returns:

  • (Boolean)


149
150
151
# File 'app/models/effective/datatable.rb', line 149

def empty?
  total_records.to_i == 0
end

#finalize(collection) ⇒ Object

Override me if you like



110
111
112
# File 'app/models/effective/datatable.rb', line 110

def finalize(collection) # Override me if you like
  collection
end

#model_nameObject

Instance method. In Rails 4.2 this needs to be defined on the instance, before it was on the class



94
95
96
# File 'app/models/effective/datatable.rb', line 94

def model_name # Searching & Filters
  @model_name ||= ActiveModel::Name.new(self.class)
end

#order_directionObject



164
165
166
167
168
169
170
171
172
# File 'app/models/effective/datatable.rb', line 164

def order_direction
  @order_direction ||= if params[:order].present?
    params[:order].first[1][:dir] == 'desc' ? 'DESC' : 'ASC'
  elsif default_order.present?
    default_order.values.first.to_s.downcase == 'desc' ? 'DESC' : 'ASC'
  else
    'ASC'
  end
end

#order_nameObject



153
154
155
156
157
158
159
160
161
162
# File 'app/models/effective/datatable.rb', line 153

def order_name
  @order_name ||= begin
    if params[:order] && params[:columns]
      order_column_index = (params[:order].first[1][:column] rescue '0')
      (params[:columns][order_column_index] || {})[:name]
    elsif default_order.present?
      default_order.keys.first
    end || table_columns.keys.first
  end
end

#pageObject



232
233
234
# File 'app/models/effective/datatable.rb', line 232

def page
  params[:start].to_i / per_page + 1
end

#per_pageObject



211
212
213
214
215
216
217
218
219
220
221
# File 'app/models/effective/datatable.rb', line 211

def per_page
  length = (params[:length].presence || default_entries).to_i

  if length == -1
    9999999
  elsif length > 0
    length
  else
    25
  end
end

#per_page=(length) ⇒ Object



223
224
225
226
227
228
229
230
# File 'app/models/effective/datatable.rb', line 223

def per_page=(length)
  case length
  when Integer
    params[:length] = length
  when :all
    params[:length] = -1
  end
end

#present?Boolean

Returns:

  • (Boolean)


145
146
147
# File 'app/models/effective/datatable.rb', line 145

def present?
  total_records.to_i > 0
end

#search_column(collection, table_column, search_term) ⇒ Object

This is here so classes that inherit from Datatables can can override the specific where clauses on a search column



203
204
205
206
207
208
209
# File 'app/models/effective/datatable.rb', line 203

def search_column(collection, table_column, search_term)
  if table_column[:array_column]
    array_tool.search_column_with_defaults(collection, table_column, search_term)
  else
    table_tool.search_column_with_defaults(collection, table_column, search_term)
  end
end

#search_termsObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'app/models/effective/datatable.rb', line 186

def search_terms
  @search_terms ||= HashWithIndifferentAccess.new().tap do |terms|
    if params[:columns].present? # This is an AJAX request from the DataTable
      (params[:columns] || {}).each do |_, column|
        next if table_columns[column[:name]].blank? || (column[:search] || {})[:value].blank?

        terms[column[:name]] = column[:search][:value]
      end
    else # This is the initial render, and we have to apply default search terms only
      table_columns.each do |name, values|
        terms[name] = values[:filter][:selected] if values[:filter][:selected].present?
      end
    end
  end
end

#table_columnsObject

Select only col == true columns, and then set the col accordingly



115
116
117
118
119
# File 'app/models/effective/datatable.rb', line 115

def table_columns
  @table_columns ||= table_columns_with_defaults().select do |_, col|
    col[:if] == nil || (col[:if].respond_to?(:call) ? (view || self).instance_exec(&col[:if]) : col[:if])
  end.each_with_index { |(_, col), index| col[:index] = index }
end

#to_jsonObject



134
135
136
137
138
139
140
141
142
143
# File 'app/models/effective/datatable.rb', line 134

def to_json
  raise 'Effective::Datatable to_json called with a nil view.  Please call render_datatable(@datatable) or @datatable.view = view before this method' unless view.present?

  @json ||= {
    :draw => (params[:draw] || 0),
    :data => (table_data || []),
    :recordsTotal => (total_records || 0),
    :recordsFiltered => (display_records || 0)
  }
end

#to_keyObject

Searching & Filters



91
# File 'app/models/effective/datatable.rb', line 91

def to_key; []; end

#to_paramObject



98
99
100
# File 'app/models/effective/datatable.rb', line 98

def to_param
  self.class.name.underscore.parameterize
end