Class: Effective::DatatableColumnTool

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(datatable) ⇒ DatatableColumnTool

Returns a new instance of DatatableColumnTool.



8
9
10
11
12
13
14
15
16
# File 'app/models/effective/datatable_column_tool.rb', line 8

def initialize(datatable)
  @datatable = datatable

  if datatable.active_record_collection?
    @columns = datatable.columns.select { |_, col| col[:sql_column].present? || (col[:search_method].present? && col[:sql_column] != false) }
  else
    @columns = {}
  end
end

Instance Attribute Details

#columnsObject (readonly)

Returns the value of attribute columns.



6
7
8
# File 'app/models/effective/datatable_column_tool.rb', line 6

def columns
  @columns
end

#datatableObject (readonly)

Returns the value of attribute datatable.



5
6
7
# File 'app/models/effective/datatable_column_tool.rb', line 5

def datatable
  @datatable
end

Instance Method Details

#order(collection) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'app/models/effective/datatable_column_tool.rb', line 30

def order(collection)
  return collection unless ordered.present?

  collection = if ordered[:sort_method]
    datatable.dsl_tool.instance_exec(collection, datatable.order_direction, ordered, ordered[:sql_column], &ordered[:sort_method])
  else
    order_column(collection, datatable.order_direction, ordered, ordered[:sql_column])
  end

  raise 'sort method must return an ActiveRecord::Relation object' unless collection.kind_of?(ActiveRecord::Relation)

  collection
end

#order_column(collection, direction, column, sql_column) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'app/models/effective/datatable_column_tool.rb', line 44

def order_column(collection, direction, column, sql_column)
  Rails.logger.info "COLUMN TOOL: order_column #{column.to_s} #{direction} #{sql_column}" if EffectiveDatatables.debug

  if column[:sql_as_column]
    collection.order(Arel.sql("#{sql_column} #{datatable.effective_resource.sql_direction(direction)}"))
  else
    Effective::Resource.new(collection)
      .order(column[:name], direction, as: column[:as], sort: column[:sort], sql_column: column[:sql_column], limit: datatable.limit)
  end
end

#orderedObject



26
27
28
# File 'app/models/effective/datatable_column_tool.rb', line 26

def ordered
  @ordered_column ||= columns[datatable.order_name]
end

#paginate(collection) ⇒ Object



84
85
86
# File 'app/models/effective/datatable_column_tool.rb', line 84

def paginate(collection)
  collection.limit(datatable.limit).offset(datatable.offset)
end

#scope(collection) ⇒ Object



55
56
57
58
59
# File 'app/models/effective/datatable_column_tool.rb', line 55

def scope(collection)
  return collection unless scoped.present?

  collection.send(scoped[:name], *scoped[:args])
end

#scopedObject



18
19
20
# File 'app/models/effective/datatable_column_tool.rb', line 18

def scoped
  @scoped ||= datatable._scopes[datatable.scope]
end

#search(collection) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/effective/datatable_column_tool.rb', line 61

def search(collection)
  searched.each do |name, value|
    column = columns[name]

    collection = if column[:search_method]
      datatable.dsl_tool.instance_exec(collection, value, column, column[:sql_column], &column[:search_method])
    else
      search_column(collection, value, column, column[:sql_column])
    end

    raise 'search method must return an ActiveRecord::Relation object' unless collection.kind_of?(ActiveRecord::Relation)
  end

  collection
end

#search_column(collection, value, column, sql_column) ⇒ Object



77
78
79
80
81
82
# File 'app/models/effective/datatable_column_tool.rb', line 77

def search_column(collection, value, column, sql_column)
  Rails.logger.info "COLUMN TOOL: search_column #{column.to_s} value=#{value} operation=#{column[:search][:operation]} column=#{sql_column}" if EffectiveDatatables.debug

  Effective::Resource.new(collection)
    .search(column[:name], value, as: column[:as], operation: column[:search][:operation], column: sql_column)
end

#searchedObject



22
23
24
# File 'app/models/effective/datatable_column_tool.rb', line 22

def searched
  @searched ||= datatable.search.select { |name, _| columns.key?(name) }
end

#size(collection) ⇒ Object

Not every ActiveRecord query will work when calling the simple .count Custom selects:

User.select(:email, :first_name).count will throw an error

Grouped Queries:

User.all.group(:email).count will return a Hash


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'app/models/effective/datatable_column_tool.rb', line 93

def size(collection)
  count = (collection.size rescue nil)

  case count
  when Integer
    count
  when Hash
    count.size  # This represents the number of displayed datatable rows, not the sum all groups (which might be more)
  else
    if collection.klass.connection.respond_to?(:unprepared_statement)
      collection_sql = collection.klass.connection.unprepared_statement { collection.to_sql }
      (collection.klass.connection.exec_query("SELECT COUNT(*) FROM (#{collection_sql}) AS datatables_total_count").rows[0][0] rescue 1)
    else
      (collection.klass.connection.exec_query("SELECT COUNT(*) FROM (#{collection.to_sql}) AS datatables_total_count").rows[0][0] rescue 1)
    end.to_i
  end
end