Module: Datagrid::Columns::InstanceMethods

Defined in:
lib/datagrid/columns.rb

Overview

ClassMethods

Instance Method Summary collapse

Instance Method Details

#assetsObject


221
222
223
224
225
226
227
# File 'lib/datagrid/columns.rb', line 221

def assets
  append_column_preload(
    driver.append_column_queries(
      super, columns.select(&:query)
    )
  )
end

#available_columnsObject

Returns all columns that are possible to be displayed for the current grid object

class MyGrid
  filter(:search) {|scope, value| scope.full_text_search(value)}
  column(:id)
  column(:name, :mandatory => true)
  column(:search_match, :if => proc {|grid| grid.search.present? }) do |model, grid|
    search_match_line(model.searchable_content, grid.search)
  end
end

grid = MyGrid.new
grid.columns # => [ #<Column:name> ]
grid.available_columns # => [ #<Column:id>, #<Column:name> ]
grid.search = "keyword"
grid.available_columns # => [ #<Column:id>, #<Column:name>, #<Column:search_match> ]

430
431
432
433
434
# File 'lib/datagrid/columns.rb', line 430

def available_columns
  columns_array.select do |column|
    column.enabled?(self)
  end
end

#column(name, query = nil, **options, &block) ⇒ Object

Defines a column at instance level

See Datagrid::Columns::ClassMethods#column for more info


404
405
406
# File 'lib/datagrid/columns.rb', line 404

def column(name, query = nil, **options, &block)
  self.class.define_column(columns_array, name, query, **options, &block)
end

#column_by_name(name) ⇒ Object

Finds a column definition by name


352
353
354
# File 'lib/datagrid/columns.rb', line 352

def column_by_name(name)
  self.class.find_column_by_name(columns_array, name)
end

#columns(*args, data: false, html: false) ⇒ Object

Returns all columns selected in grid instance

Examples:

MyGrid.new.columns # => all defined columns
grid = MyGrid.new(:column_names => [:id, :name])
grid.columns # => id and name columns
grid.columns(:id, :category) # => id and category column

333
334
335
336
337
338
339
# File 'lib/datagrid/columns.rb', line 333

def columns(*args, data: false, html: false)
  self.class.filter_columns(
    columns_array, *args, data: data, html: html
  ).select do |column|
    column.enabled?(self)
  end
end

#data(*column_names) ⇒ Object

Returns Array of Arrays with data for each row in datagrid assets with header.

Arguments:

* <tt>column_names</tt> - list of column names if you want to limit data only to specified columns

274
275
276
# File 'lib/datagrid/columns.rb', line 274

def data(*column_names)
  self.rows(*column_names).unshift(self.header(*column_names))
end

#data_columns(*names, **options) ⇒ Object

Returns all columns that can be represented in plain data(non-html) way


342
343
344
# File 'lib/datagrid/columns.rb', line 342

def data_columns(*names, **options)
  self.columns(*names, **options, data: true)
end

#data_hashObject

Return Array of Hashes where keys are column names and values are column values for each row in filtered datagrid relation.

Example:

class MyGrid
  scope { Model }
  column(:id)
  column(:name)
end

Model.create!(:name => "One")
Model.create!(:name => "Two")

MyGrid.new.data_hash # => [{:name => "One"}, {:name => "Two"}]

294
295
296
297
298
# File 'lib/datagrid/columns.rb', line 294

def data_hash
  map_with_batches do |asset|
    hash_for(asset)
  end
end

#data_row(asset) ⇒ Object

Returns an object representing a grid row. Allows to access column values

Example:

class MyGrid
  scope { User }
  column(:id)
  column(:name)
  column(:number_of_purchases) do |user|
    user.purchases.count
  end
end

row = MyGrid.new.data_row(User.last)
row.id # => user.id
row.number_of_purchases # => user.purchases.count

397
398
399
# File 'lib/datagrid/columns.rb', line 397

def data_row(asset)
  ::Datagrid::Columns::DataRow.new(self, asset)
end

#data_value(column_name, asset) ⇒ Object

Return a cell data value for given column name and asset


437
438
439
440
441
442
443
444
# File 'lib/datagrid/columns.rb', line 437

def data_value(column_name, asset)
  column = column_by_name(column_name)
  cache(column, asset, :data_value) do
    raise "no data value for #{column.name} column" unless column.data?
    result = generic_value(column, asset)
    result.is_a?(Datagrid::Columns::Column::ResponseFormat) ? result.call_data : result
  end
end

#decorate(model) ⇒ Object

Returns a decorated version of given model if decorator is specified or the model otherwise.


460
461
462
# File 'lib/datagrid/columns.rb', line 460

def decorate(model)
  self.class.decorate(model)
end

#format(value, &block) ⇒ Object

Gives ability to have a different formatting for CSV and HTML column value.

Example:

column(:name) do |model|
  format(model.name) do |value|
    (:strong, value)
  end
end

column(:company) do |model|
  format(model.company.name) do
    render :partial => "company_with_logo", :locals => {:company => model.company }
  end
end

371
372
373
374
375
376
377
378
# File 'lib/datagrid/columns.rb', line 371

def format(value, &block)
  if block_given?
    self.class.format(value, &block)
  else
    # don't override Object#format method
    super
  end
end

#generic_value(column, model) ⇒ Object

:nodoc:


464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
# File 'lib/datagrid/columns.rb', line 464

def generic_value(column, model) #:nodoc:
  cache(column, model, :generic_value) do
    presenter = decorate(model)
    unless column.enabled?(self)
      raise Datagrid::ColumnUnavailableError, "Column #{column.name} disabled for #{inspect}"
    end

    if column.data_block.arity >= 1
      Datagrid::Utils.apply_args(presenter, self, data_row(model), &column.data_block)
    else
      presenter.instance_eval(&column.data_block)
    end
  end

end

#hash_for(asset) ⇒ Object

Returns Hash where keys are column names and values are column values for the given asset


250
251
252
253
254
255
256
# File 'lib/datagrid/columns.rb', line 250

def hash_for(asset)
  result = {}
  self.data_columns.each do |column|
    result[column.name] = data_value(column, asset)
  end
  result
end

#header(*column_names) ⇒ Object

Returns Array of human readable column names. See also “Localization” section

Arguments:

* <tt>column_names</tt> - list of column names if you want to limit data only to specified columns

234
235
236
# File 'lib/datagrid/columns.rb', line 234

def header(*column_names)
  data_columns(*column_names).map(&:header)
end

#html_columns(*names, **options) ⇒ Object

Returns all columns that can be represented in HTML table


347
348
349
# File 'lib/datagrid/columns.rb', line 347

def html_columns(*names, **options)
  self.columns(*names, **options, html: true)
end

#html_value(column_name, context, asset) ⇒ Object

Return a cell HTML value for given column name and asset and view context


447
448
449
450
451
452
453
454
455
456
457
# File 'lib/datagrid/columns.rb', line 447

def html_value(column_name, context, asset)
  column  = column_by_name(column_name)
  cache(column, asset, :html_value) do
    if column.html? && column.html_block
      value_from_html_block(context, asset, column)
    else
      result = generic_value(column, asset)
      result.is_a?(Datagrid::Columns::Column::ResponseFormat) ? result.call_html(context) : result
    end
  end
end

#initializeObject

:nodoc:


408
409
410
411
# File 'lib/datagrid/columns.rb', line 408

def initialize(*) #:nodoc:
  self.columns_array = self.class.columns_array.clone
  super
end

#row_for(asset, *column_names) ⇒ Object

Returns Array column values for given asset

Arguments:

* <tt>column_names</tt> - list of column names if you want to limit data only to specified columns

243
244
245
246
247
# File 'lib/datagrid/columns.rb', line 243

def row_for(asset, *column_names)
  data_columns(*column_names).map do |column|
    data_value(column, asset)
  end
end

#rows(*column_names) ⇒ Object

Returns Array of Arrays with data for each row in datagrid assets without header.

Arguments:

* <tt>column_names</tt> - list of column names if you want to limit data only to specified columns

263
264
265
266
267
# File 'lib/datagrid/columns.rb', line 263

def rows(*column_names)
  map_with_batches do |asset|
    self.row_for(asset, *column_names)
  end
end

#to_csv(*column_names, **options) ⇒ Object

Returns a CSV representation of the data in the grid You are able to specify which columns you want to see in CSV. All data columns are included by default Also you can specify options hash as last argument that is proxied to Ruby CSV library.

Example:

grid.to_csv
grid.to_csv(:id, :name)
grid.to_csv(:col_sep => ';')

311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/datagrid/columns.rb', line 311

def to_csv(*column_names, **options)
  require "csv"
  CSV.generate(
    headers: self.header(*column_names),
    write_headers: true,
    **options
  ) do |csv|
    each_with_batches do |asset|
      csv << row_for(asset, *column_names)
    end
  end
end