Skip to content

A Ruby on Rails Engine plugin that makes it easy to import CSV files, complete with error reporting and customization.

License

Notifications You must be signed in to change notification settings

dallas/csv_import

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CsvImport

This is a Rails plugin.

It provides a controller method called each_csv_row and an accompanying view helper called csv_fields.

You can set the name of the file field param by passing it as the first argument to the csv_fields helper (it is ‘csv_file’ by default):

<%= csv_fields :csv_file_upload %>

You may also specify the file field param as the first argument to the each_csv_row method in the controller (it too is ‘csv_file’ by default):

each_csv_row(:csv_file_upload) do |row_hash|
  # …
end

By default, when each_csv_row is called, any exceptions raised in the block will be rescued. The rows that triggered the exceptions will then be displayed in a table as part of the output from csv_fields.

You can turn off rescuing by passing false as the second argument to each_csv_row:

each_csv_row(:csv_file_upload, false) do |row_hash|
  # …
end

each_csv_row extracts the names of the fields from the CSV and applies them to each row in the CSV creating a hash of key / value pairs. The resulting hash for a row from the example below would look something like this:

{:first_name => 'Bob', :last_name => 'Smith'}

If the first row does not contain the field names, each_csv_row names them from 0 to the length (- 1) of the first row:

{0 => 'Bob', 1 => 'Smith'}

Example

In your controller:

class EmployeesController < ActionController::Base
  include CsvImport

  def import_employee_records
    each_csv_row do |row_hash|
      Employee.destroy_all if params[:destroy_all_first]
      Employee.create!(row_hash)
    end
  end
end

In your view (don’t forget to set :multipart => true):

<h2>Import Employee Records</h2>

<%- form_tag import_employees_path, {:multipart => true} do -%>

  <%= csv_fields %>

  <p>
    <%= check_box_tag :destroy_all_first %>
    <%= label :destroy_all_first, 'Destroy all existing employee records first.' %>
  </p>
<%- end -%>

Other View Helpers Included

All of these are called in csv_fields. These exist for flexibility’s sake. Feel free to mix and match or even override csv_fields in your own helper.

csv_file_label(name = 'csv_file', text = 'CSV file to use', options = {})

csv_file_tag(name = 'csv_file', options = {})

csv_field_names_label(name = 'csv_field_names_in_first_row', text = 'Field name labels are in the first row.', options = {})

csv_field_names_check_box_tag(name = 'csv_field_names_in_first_row', value = '1', checked = true, options = {})

csv_rows_imported_content(wrapping_tag = :div, html_options = {})

csv_bad_rows_table(header = 'Bad CSV rows', html_options = {})

To-do

Allow for mapping of incoming field name labels to expected or preferred keys:

each_csv_row(:non_useful_key_name => :key_expected, :other_key => :better_key) do |row_hash|
  # …
end

Or even…

each_csv_row(0 => :first_name, 1 => :last_name, 2 => :email) do |row_hash|
  # …
end

Move the view helper methods to FormHelper, FormHelper::InstanceTag, and FormBuilder

Specifically FormBuilder so that things like this are made possible:

<%- form_for @company do |f| -%>
  <p>
    <%= f.label :name, 'Company Name' %><br />
    <%= f.text_field :name %>
  </p>

  # yadda, yadda

  <p>
    <%= f.csv_file_label :employees_csv_file, 'Import Employees from a CSV' %><br />
    <%= f.csv_file :employees_csv_file %>
  </p>

  <p><%= f.submit 'Save' %></p>
<%- end -%>

About

A Ruby on Rails Engine plugin that makes it easy to import CSV files, complete with error reporting and customization.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Ruby 100.0%