Tom Bom
Tom Bom

Reputation: 1721

How to upload correctly CSV file in Rails

I am trying to upload a csv file with Rails from Active Admin.

I have a model User, which has columns name(string) and age(integer).

My csv file looks like this:

name,age
"Peter",31
"Susan",30
"John",40

Then I have in my admin/user.rb:

ActiveAdmin.register User do
  permit_params :name, :age

  collection_action :upload_csv do
    render "admin/csv/upload_csv_user"
  end

  collection_action :import_csv_data_user, :method => :post do
    ret_val = CsvDb.update_model_from_csv("user", params[:dump][:file])
    redirect_to :action => :index, :notice => ret_val
  end
end

And in my admin/csv/upload_csv_user.html.erb I have:

<%= form_for(:dump, :url=>{:action=>"import_csv_data_user"}, :html => { :multipart => true }) do |f| %>
  <%= f.file_field :file %>
  <%= f.submit "Submit", confirm: "Are You Sure?" %>
<% end %>

Inside a csv_db.rb file I have:

require 'csv'
module CsvDb

  def self.update_model_from_csv(model_name, file)
    csv_data = CSV.read(file.path)
    columns = csv_data.shift
    model = model_name.classify.constantize
    ret_val = "Data updated successfully!"
    begin
      model.import columns, csv_data, on_duplicate_key_update: columns, validate: false
    rescue Exception => e
      ret_val = e
    end
    ret_val
  end
end

When I try to upload the file I get the following error: Illegal quoting in line 1.

And below it's written:

part "\"name"
parse "\"name,age\""
parts ["\"name", "age\""]
unconverted nil
in_extended_col false
csv []

I checked lots of examples and I can't find the error. Maybe my csv file is formatted incorrectly.

Upvotes: 1

Views: 351

Answers (1)

Anand
Anand

Reputation: 6531

require 'csv'
module CsvDb

  def self.update_model_from_csv(model_name, file_params)
    CSV.foreach(file_params.path, headers: true) do |row|
      model = model_name.classify.constantize
      begin
        name = row["name"]
        age = row["age"]
        if model.create(name: name, age: age)
          result = "Imported successfully!"
        end
      rescue Exception => e
        result = e
      end
    end
    result
  end
end

Use this method in controller as: -

#pass model name and params[:file], which is csv uploaded from user end
CsvDb.update_model_from_csv(model_name, params[:file])

Upvotes: 1

Related Questions