Skip to content

Working with data and ActiveRecord

shairontoledo edited this page Sep 13, 2010 · 5 revisions

This is a helper object to create a tabular representation composed of rows, columns and title.

Simple array manipulation

This prototype is used to join the common attributes for data grids. To use a Grid you must first set up the columns , then load the data. Example:


 grid=RGhost::Grid::Matrix.new
 grid.column :title => "Code", :width => 1
 grid.column :title => "Name", :width => 3, :align => :center
 grid.column :title => "Date", :width => 3, :align => :center

Note that both the width and alignment of the last two columns are identical. To avoid this, you can specify a default width by passing the values to the DataGrid::Grid object constructor, so any columns that do not specify these values will use them. Example:


 grid=RGhost::Grid::Matrix.new :width => 3, :align => :center
 grid.column :title => "Code", :width => 1    #:width => 1, :align => :center
 grid.column :title => "Name"                 #:width => 3, :align => :center
 grid.column :title => "Date"                 #:width => 3, :align => :center

The actual content needs to be passed in as an array of arrays

  values=[
    [1,"Name 1", Time.now],
    [2,"Name 2", Time.now],
    [3,"Name 3", Time.now],
    [4,"Name 4", Time.now],
    [5,"Name 5", Time.now]
  ]

Bind the content to the grid:


 grid.data(values)

Add the Grid to a document


 d=RGhost::Document.new
 d.set grid

Importing CSV

RGhost::Grid::CSV allows you to import data from a csv file.

Example


 grid=Grid::CSV.new :width => 2 
 grid.column :title => "User", :align => :right 
 grid.column :title => "Password", :format => lambda{|v| (v.to_s == "x") ? "Yes" : "No"} 
 grid.column :title => "UID", :width => 1 
 grid.column :title => "GID" 
 grid.column :title => "Gecos", :width => 2.5 
 grid.column :title => "Home Dir", :width => 4 
 grid.column :title => "Shell" 
 grid.style  :bottom_lines 
 grid.data("/etc/passwd",/:/) 

result

Active Record and Rails

RGhost::Grid::Rails differs from the other grids only in the mapping of the model attributes to be printed in the column. For example, the class Calls inherits ActiveRecord::Base.

Example


  rails_grid=Grid::Rails.new(:align => :center, :width => 3) 

Map the attribute name then the already known options


 rails_grid.column :mobile,   :title => "Mobile", :align => :right 
 rails_grid.column :duration, :title => "Duration",:width => 3 
 rails_grid.column :start,    :title => "Start", :format => :eurodate 
 rails_grid.column :called,   :title => "Number", :align => :right, :title_align => :center 

Loading data


  calls = Call.find(:all, :limit => 5000) 
  rails_grid.data(calls) 

Relationships

For relationships we use a block or a String instead of an attribute name (Symbol). Example


  class Accounts < ActiveRecord::Base 
    belongs_to :customer 
  end 

  class Customers < ActiveRecord::Base 
    has_many :accounts 
  end 

  c = Customers.find(:all, :include => :accounts ) 

Using a block


  g=RGhost::Grid::Rails.new  :width => 4 
  g.column :id,         :title => "Customer id" 
  g.column :name,       :title => "Name",   :width => 6 
  g.column :created_on, :title => "Date ",  :format => lambda{|d| d.strftime("%m/%d/%Y") } 
  g.column lambda { accounts.first.login }, :title => "Login" 
  g.column lambda { accounts.first.type },  :title => "Account Type" 
  g.data(c) 

Or a String


  g.column 'accounts.first.login', :title => Login"

For versions greater than 0.8.5 you can use the facade method Document#rails_grid, like below


 doc=RGhost::Document.new
 doc.rails_grid :width => 4 do |grid|
    grid.column :id,         :title => "Customer id" 
    grid.column :name,       :title => "Name",   :width => 6 
    grid.column :created_on, :title => "Date ",  :format => lambda{|d| d.strftime("%m/%d/%Y") } 
    grid.column lambda { accounts.first.login }, :title => "Login" 
    grid.column lambda { accounts.first.type },  :title => "Account Type" 
    grid.data(c) 
 end

Field Format

Defines the format of data using :format parameters option.

:format – Format of the data. You can format data in four different ways with Rghost, by passing in a Symbol, a String, a Class or Proc.

:format Parameters type

Symbol – Searches for a method defined as Grid::FieldFormat::method_name


 :format => :eurodate

Class – A class that inherits Grid::FieldFormat::Custom with an overridden format method.


 :format => MyFormat

String – Formats using the same parameters used in sprintf


 :format => "%0.2f"

Proc – A block. In the example a text limited to 9 characters.


 :format => lambda {|s| s.gsub(/^(.{9}).*$/,'\1...')}

Customizing formats

Let’s create a class that replaces empty spaces with a double dash.


 class MyFormat < RGhost::Grid::FieldFormat::Custom
   def format
     @value.to_s.gsub(/ /,'--')
   end
 end

Using


 grid.column :title => "Name", :format => MyFormat

Below, the columns with their proper formats.


 grid.column :title => "Code",:format => "(%d)", :width => 1
 grid.column :title => "Name",  :format => MyFormat
 grid.column :title => "Date",  :format => lambda {|date| date.strftime("%d/%m/%Y") }
 values=[
  [1,"Name 1", Time.now],
  [2,"Name 2", Time.now],
  [3,"Name 3", Time.now],
  [4,"Name 4", Time.now],
  [5,"Name 5", Time.now]
 ]
 grid.data(values)

Add the Grid to a document


 d=RGhost::Document.new
 d.set grid

Preset Styles

Grid has 3 preset styles :bottom_lines, :border_lines and old_forms. To set any of them, use:


  grid.style(:border_lines)

:border_lines – instance of RGhost::Grid::Style::BorderLines

:bottom_lines – instance of RGhost::Grid::Style::BottomLines

:old_forms – instance of RGhost::Grid::Style::OldForms

Grid Callbacks

The callbacks for the grid are defined here. Let‘s see them in action.
Grid::CallbackFacade examples


 grid=RGhost::Grid::Matrix.new :column_padding => 1
 grid.column :title => "Id", :width => 1
 grid.column :title => "Name", :width => 3, :align => :center
 grid.column :title => "Date", :width => 3, :align => :right, :title_align => :center,   :format => lambda{|v| v.strftime("%d/%m/%Y")}
 values=('A'..'E').to_a.map{|v|  [v,"Name #{v}", Time.now]}

Use even_row:


 grid.even_row do |r|
  r.background_row(:size => grid.width)
 end

Now use before_row to create a top and bottom line:


 grid.before_row do |r|
  r.horizontal_line(:top,    :size => grid.width )
  r.horizontal_line(:bottom, :size => grid.width)
 end

before_column:


 grid.before_column do |c|
  c.vertical_line_row
 end

after_column


 grid.after_column {|e|  e.vertical_line_row  }

Modifying the header


 grid.header.before_create do |b|
  b.horizontal_line(:top, :size => grid.width)
 end

Finishing the grid lines:


 grid.header.before_column do |b|
   b.vertical_line_row
 end

 grid.header.after_column do |a|
   a.vertical_line_row
 end

Now, adding a bold font to the header


 grid.header.before_create do |b|
   b.horizontal_line(:top, :size => grid.width)
   b.use_tag :bold
  end

Oops. Not quite what we expected, since the entire grid used a bold font. We can use the header callback after_create to reset the font.


 grid.header.after_create do |a|
    a.use_tag :normal
  end

or use RGhost::Document#rails_grid like above.