Description

ar_to_html_table renders an ActiveRecord result set into an html_table. For example:

Product.all.to_table

will produce a table with default characteristics. These characteristics are primarily driven by class names and hence styling is defined in CSS.

Usage

ar_to_html_table consists of two parts:

  • Defining column formats in the ActiveRecord model
  • Rendering an ActiveRecord result set

Column definitions

Columns in the table are formatted based upon a column definition applied in the Model. Some examples:

class Product < ActiveRecord::Base
  column_format :name,      :order => 1
  column_format :orders,    :total => :sum
  column_format :revenue,   :total => :sum, :order => 5, :class => 'right'
  column_format :age, 	    :total => :avg, :order => 20, :class => 'right', :formatter => :number_with_delimiter
  ....
end

The general form of a column definition is:

column_format :column_name, options

Column names and calculated columns

Column names are generally the model attribute name however a limited set of calculated columns can also be derived. For example:

column_format :percentage_of_revenue, :order => 9, :class => 'right'

Will define a column that renders the percentage of total revenue that this row’s revenue represents. The regexp used to recognize calculated columns is:

/(percent|percentage|difference|diff)_of_(.*)/

Where the match is the name of the column against which the calculation if made. Therefore percentage and difference (plus their variants) are the two available calculated column types.

Column options

Option Description
:order Positions a column order relative to other columns. The number isn’t important, just its relative value compared to other columns. Columns are sorted by order and rendered in that order. The default order is the order in which the columns are defined.
:total Renders a table footer with a calculation of all the values in the column. The available totaling methods are :sum, :count and :average (or :avg or :mean)
:class The CSS class for this column. Note that a colgroup is defined for each column and each colgroup has as CSS class that is the column name
:formatter A :symbol representing a method to format the value of each table cell. There are several predefined formatters but any method with a signature of method(value, options = {}) will work, including the methods in ActionView::Helpers::NumberHelper. Lastly a lambda can be provided for arbitrary formatting.

Predefined formatters

Formatter Description
:float_with_precision Calls #number_with_precision after #to_f on the value.
:integer_with_delimiter Calls #integer_with_delimiter unless I18n::Backend::Simple.included_modules.include? Cldr::Format is true in which case I18n.localize is called.
:seconds_to_time Formats an integer as hh:mm:ss, mostly used for durations, not time or datetime columns
:hours_to_time Formats an integer as hh:00.
:currency_without_sign Calls #number_with_precision with precision 2.
:percentage An integer rendered as a percentage. Calls #number_to_percentage with a precision of 1.
:bar_and_percentage Displays a CSS bar and a percentage.
:unknown_on_blank Displays (unknown) when column.blank? is true. This is a localized value. The key I18n.t(‘tables.unknown’) is used.
:not_set_on_blank Displays (not set) when column.blank? is true. This is a localized value. The key I18n.t(‘tables.not_set’) is used.

If no formatter is specified then:

  • string and text values are used unmodified
  • date and datetime values are called on to_s(:db)
  • integers and floats are called on number_with_delimiter
  • to_s is called on all other column types.

Table rendering

To render the html table, call to_table(options) on any ActiveRecord result set. The default options are:

:exclude      => EXCLUDE_COLUMNS, 
:exclude_ids  => true, 
:odd_row      => "odd", 
:even_row     => "even", 
:totals       => true,
:total_one    => 'tables.total_one',
:total_many   => 'tables.total_many',
:unknown_key  => 'tables.unknown',
:not_set_key  => 'tables.not_set',
:heading      => nil,
:caption      => nil,
:sort         => nil
Option Description
:include Array of columns that should be rendered
:exclude Array of columns that should not be rendered
:exclude_ids Don’t render columns that end in _id
:sort A Proc that is called to sort the rows. Called as results.sort(options[:sort]).
:heading A table heading that is placed in the first row of a table
:caption A table caption applied
:odd_row CSS class name for odd rows
:even_row CSS class name for even rows
:totals Add a total row at the bottom of the table
:total_one I18n key for rendering the total row when the total is one
:total_many I18n key for rendering the total row when the total is not one
:unknown_key I18n key for rendering (Unknown)
:not_set_key I18n key for rendering (Not Set)

Using formatters outside ar_to_html_table

Once defined the formatters can be used in other places. Both class and instance methods are provided. Best explained by the following example:

  class Product < ActiveRecord::Base
     column_format :name,      :order => 1
     column_format :orders,    :total => :sum
     column_format :revenue,   :total => :sum, :order => 5, :class => 'right'
     column_format :age,       :total => :avg, :order => 20, :class => 'right', :formatter => :number_with_delimiter
   end
   p = Product.first
   => #<Product id: 55986, age: 4346, .........
   p.age
   => 4346
   p.format_column(:age)
   => "4,346"

License

(The MIT License)

Copyright © 2010 Kip Cole

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.