A rails plugin for download csv.
Ruby JavaScript
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
test
.gitignore
Gemfile
Gemfile.lock
Gemfile.rails-3.2
Gemfile.rails-edge
MIT-LICENSE
README.rdoc
Rakefile
csv_rails.gemspec

README.rdoc

CsvRails

CsvRails provides a simple way of download csv in Rails 3.

Supported versions

Ruby 1.9 (1.8 not supported) Rails 3 ActiveRecord or Mongoid

Install

To use CsvRails simply add the line

gem 'csv_rails'

to your Gemfile and then run

bundle install

Example

class UsersController < ApplicationController
  def index
    @users = User.all

    respond_to do |format|
      format.html { @users = @users.all }
      format.json { render json: @users }
      format.csv{ render csv: @users, fields: [:id, :name, :age], encoding: 'SJIS', without_header: true }
    end
  end

Usage

Download

If you want formatted attribute, CsvRails call “#{attribute}_as_csv”. For example, you wish formatted created_at then you write like this.

class User < ActiveRecord::Base
  def created_at_as_csv
    created_at.strftime("%F %H:%M")
  end
end

CsvRails define a singleton method Array.to_csv, and the method accept fields option. The fields option can not only database fields also method and method chain.

class User < ActiveRecord::Base
  has_many :memberships
  has_many :groups, through: :memberships

  def ok
    "OK"
  end
end

class UsersController < ApplicationController
  def index
    @users = User.all

    respond_to do |format|
      format.csv{ render csv: @users, fields: [:ok, :"groups.first.name"], encoding: 'SJIS' }
    end
  end

If you do not use :header option, header is using :fields and I18n transfer.

# config/locales/ja.yml
ja:
  activerecord:
    attributes:
      group: &groupmodel
        name: グループ名
      user:
        id: ID
        name: 名前
        age: 年齢
        ok: OK
      # rails3
        groups:
          first:
            <<: *groupmodel
      # rails 3.2.3 - 3.2.5
      user/groups:
        first:
          <<: *groupmodel
      # rails 3.2.6 or higher
      groups/first:
        <<: *groupmodel

# app/controllers/user_controller.rb
def index
  @users = User.where("id < 1").all
  respond_to do |format|
    format.csv{ render csv: @users, fields: [:ok, :"groups.first.name"], encoding: 'SJIS' } #=> "OK,グループ名"
  end
end

And you can use tsv. Both tsv and csv can accept row_sep option.

# app/controllers/user_controller.rb
def index
  @users = User.all
  respond_to do |format|
    format.csv{ render csv: @users, :row_sep => "\r\n" }
    format.tsv{ render tsv: @users, :row_sep => "\r\n" }
  end
end

You also use i18n_scope option

# config/locales/ja.yml
ja:
  csv:
    name: なまえ

User.where("id < 1").all.to_csv(:i18n_scope => :csv) #=> "なまえ\n"

Upload

CSVRails is also have upload concern.

You should include CSVRails::Import into your model.

example

# app/model/user.rb
class User < ActiveRecord::Base
  attr_accessor :file
  include CsvRails::Import
....

And render file_field into form

example

# app/views/users/index.html.erb

<%= form_for(@user, multipart: true) do |f| %>
  File: <%= f.file_field :file %>
  <%= f.submit 'Upload' %>
<% end %>

Next implement action

# app/controllers/users_controller.rb

def create
  if params[:format] == 'csv'
    users = User.csv_import(params[:file])
    if users.find{|u| u.errors.any? }
      render :index
    else
      redirect_to users_path, notice: 'Upload success'
    end
  end
end

csv_import is be able to use block.

User.csv_import(params[:file]) do |user, params, row_number|
  next false if row_number == 2 # 'next false' in the block, the line is skipped.
end

csv_import use transaction, if invalid line is existed then all rows is not imported.

First line used for fields, but you can manually choose it using options

User.csv_import(params[:file], fields: [:age, :name])

It line first line has 'id', csv_import call where(id: id).first_or_initialize, but you can use other field name

User.csv_import(params[:file], find_key: :name)
#=> It call User.where(name: name).first_or_initialize internal.

Copyright © 2012-2013 yalab, released under the MIT license