Fetching contributors…
Cannot retrieve contributors at this time
145 lines (98 sloc) 2.78 KB

CSV Shaper

Beautiful DSL for creating CSV output in Ruby & Rails.

Creating CSV files in Ruby is painful! CSV Shaper makes life easier! It's ideal for converting database backed models with attrbiutes into CSV output. It can be used without Rails, but works great with ActiveRecord models and even comes with support for it's own template handling.

Example Usage

csv_string = CsvShaper::Shaper.encode do |csv|
  csv.header :name, :age, :gender, :pet_names
  csv.rows @users do |csv, user|
    csv.cells :name, :age, :gender
    if user.pets.any?
      csv.cell :pet_names


Install using Rubygems

$ gem install csv_shaper

Or if you want to use it in your Rails app, add the following line to your Gemfile

gem 'csv_shaper'

and then run

$ bundle install


Everything goes inside the encode block, like so

csv_string = CsvShaper::Shaper.encode do |csv|

If you're using it in Rails 3.0+ you are already inside the block so you can just call the csv object.

Create a Rails view, set the content-type to csv and the handler to shaper, like so



You must define the headers for your CSV output. This can be done in one of 3 ways.

Standard attribute list

csv.headers :name, :age, :location

This would create headers like so:


Using the attribute names of a Class

Say you have a User ActiveRecord class with attributes of :name, :age, :location. Simply pass the class to the headers method

csv.headers User

Using a block to define headers and custom mappings

csv.headers do |csv|
  csv.columns :name, :age, :location
  csv.mappings name: 'Full name', location: 'Region'

This would create headers like so:

Full name,Age,Region

Rows & Cells

CSV Shaper allows you to define rows and cells in a variety of ways.

Basic row without a model

csv.row do |csv|
  csv.cell :name, "Joe"
  csv.cell :age, 24

Passing a model and attributes

csv.row @user, :name, :age, :location

This will call the column names (name, age...) on @user and assign them to the correct cells.

Passing a model to a block

csv.row @user, do |csv, user|
  csv.cells :name, :age
  if user.show_gender?
    csv.cell :gender

  csv.cell :exported_at,

Any calls here to cell or cells without a value are called on the model (user), otherwise the second parameter is assigned.

Multiple Rows

You can pass an Enumerable and a block to csv.rows like so

csv.rows @users do |csv, user|
  csv.cells :name, :age, :location, :gender
  csv.cell :exported_at,

Copyright (c) Paul Springett 2012