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'}
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 -%>
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 = {})
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
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 -%>