Ruby on Rails CSV Upload&Import - File Name Too Long

Ruby on Rails CSV upload&import - File name too long

Thanks to the input of the other answers I found the solution myself. The problem is that .read turns the file into a string with the contents, but CSV.foreach() expects a filename or path . Using .path instead solves the problem:

 if request.post? && params[:file].present?
inputPath = params[:file].path
CSV.foreach(inputPath) do |row|
#save row here
end
end

Rails 4 Error in CSV Import

You would get that error from calling CSV.open(file.path, nil, :ignore) on any CSV, for example:

require 'csv'

# open a new CSV and write a couple of rows
CSV.open("test.csv", "w") do |csv|
csv.puts ["test", "header"]
csv.puts ["test", "data"]
end

# now try and open that same CSV with 2nd and 3rd args nil and :ignore
csv = CSV.open("test.csv", nil, :ignore)
# => TypeError: no implicit conversion of Symbol into Integer

CSV::open is documented here (for Ruby 1.9.2). The second argument should be an open mode (e.g. read, write, append) - see a list on SO - and the third can be an options hash. Continuing the above, you might try something like the following:

csv = CSV.open("test.csv", "r")
csv.readline # note there is no CSV#row method
# => ["test", "header"]
csv.readline
# => ["test", "data"}
csv.close # if you're not passing a block to CSV::open, be sure to close the file

Note that there is also a CSV::read method which can be more suitable for dealing with header rows in CSV files - have a read through the documentation to find out more.

Importing CSV's with different Column Headers each time in rails

Create a table for importing csv data to. Let's call it CsvDatum. Fix columns that are shared by all your csv's and create a third text column to store a hash containing the extra attributes. Let's say all csv's have name and email. You schema should be as follows.

  create_table "csv_data", force: :cascade do |t|
t.string "name", limit: 255
t.string "email", limit: 255
t.text "extra_columns", limit: 65535
end

In your model

class CsvDatum < ActiveRecord::Base
serialize :extra_columns, Hash
end

Now when you are reading your csv file create an instance of the CsvDatum class to hold row data.

CSV.foreach("path/to/file.csv", headers: true) do |row|
data = CsvDatum.new(name: row["name"], email: row["email"])
row.delete["name"]
row.delete["email"]
data.extra_columns = row.to_hash
data.save
end

How to best import and process very large csv files with rails

  • to import csv faster, my suggestion is using gem smarter_csv, you can cek from their website tilo/smarter_csv
  • as stated from their site: > smarter_csv is a Ruby Gem for smarter importing of CSV Files as Array(s) of Hashes, suitable for direct processing with Mongoid or ActiveRecord, and parallel processing with Resque or Sidekiq
  • I use this gem and combined with resque

below is sample code to import file

  n = SmarterCSV.process(params[:file].path) do |chunk|
Resque.enqueue(ImportDataMethod, chunk)
end

after it read file, passed the data record to resque and then import it in background (if you using rails 4.2 above you can combine with rails active job)

Problems importing a CSV that has a filename as a string in Rails

You can't use the image= method; that's a CarrierWave method (overloading ActiveRecord's) which you're misusing when trying to set a string directly.

You can instead use write_attribute

product_image.raw_write_attribute(:image, row[2])

This internally is what ActiveRecord uses inside it's image= method.

rails Import csv file, but saving blank

This line seems strange:

product.attributes = row.to_hash.slice(accepts_nested_attributes_for)

The class method accepts_nested_attributes_for has a completely different purpose than listing the attribute names of Product. But you could use attribute_names. Try this:

product.attributes = row.to_hash.stringify_keys.slice(*attribute_names)

Note that stringify_keys might be unnecessary, depending on how exactly the hash returned by row.to_hash looks. Also note that slice takes a list of attribute names, not an array. The asterisk * allows us to use the elements of an array as individual arguments to a function.

Ruby on Rails - Import Data from a CSV file

require 'csv'    

csv_text = File.read('...')
csv = CSV.parse(csv_text, :headers => true)
csv.each do |row|
Moulding.create!(row.to_hash)
end


Related Topics



Leave a reply



Submit