Jake
Jake

Reputation: 1370

Rails CSV Import - File name too long @ rb_sysopen

So my import method has the following in the OccupantsController:

def import
 @occupant = Occupant::Import.run(params[:file].path, params[:training_event_id]).result
 if @occupant.errors.empty?
  flash[:notice] = "Imported"
 else
  flash[:notice] = "You have failed this import"
 end
end

Then in my Operations > Occupant > Import I have the following:

class Occupant
class Import < Operation
require 'csv'

def call(file, training_event_id)
  csv_text = File.read(file)
  csv = CSV.parse(csv_text).to_s
  binding.pry
  list_occo = CSV.foreach(csv, headers: true, header_converters: :symbol) do |row|
    occupant = Occupant.new
    occupant.training_event_id = row[training_event_id]
    occupant.account_number = row['Account Number']
    occupant.first_name = row['First Name']
    occupant.last_name = row['Last Name']
    occupant.email = row['Email']
    occupant.hotel = row['Hotel']
    occupant.two_beds = row['Two Beds']
    occupant.company_id = row['Company ID']
    occupant.student_id = row['Student ID']
    occupant.address = row['Address']
    occupant.address_2 = row['Address 2']
    occupant.city = row['City']
    occupant.state = row['State']
    occupant.zip = row['Zip']
    occupant.phone = row['Phone']
    occupant.cancellation_agree = row['Cancellation Agree']
    occupant.share = row['Share']
    occupant.roommate = row['Roommate']
    occupant.check_in = row['Check In']
    occupant.check_out = row['Check Out']
    occupant.to_s
    validate_file = check_file(occupant)
    occupant.save if validate_file
  end
  list_occo
  binding.pry
end

This results in

Errno::ENAMETOOLONG (File name too long @ rb_sysopen - [["Account Number", "First Name",etc

I originally had in my import method and call method respectively:

Occupant::Import.run(params[:file], params[:training_event_id])

list_occo = CSV.foreach(file.path, headers: true) do |row|

However this was causing the same issue. So I thought I could just break these up and do the csv_text to handle the read and then do a parse on the file read and then convert to a string. No go.

I've also tried updating the params to do [:file].read and in the call method to use just file. Same issue.

Now if I do:

Occupant::Import.run(params[:file].path, params[:training_event_id]).result

list_occo = CSV.foreach(file, headers: true) do |row|

With this combination, no errors until I try to call on another method for validation on the files. Except...it's not generating anything.

How do I read through the file with avoiding the file name too long?

EDIT:

I've also tried in the import method:

Occupant::Import.run(params[:file].path, params[:training_event_id]).result

Then in the call method:

url_data = open(file).read()
csv_data = url_data.parse_csv.to_s
CSV.foreach(csv_data, headers: true) do |row|

This ends up with:

Errno::ENOENT (No such file or directory @ rb_sysopen

Upvotes: 2

Views: 3327

Answers (1)

arieljuod
arieljuod

Reputation: 15838

It looks like you are passing the content of the file to the CSV.foreach method, it expects a path to a file, not the actual content. The correct form would be list_occo = CSV.foreach(the_path_of_the_file, headers: true) do |row|.

I guess you can use something similar to what you already have with this:

csv_text = File.read(file_path)
csv = CSV.parse(csv_text).to_s

I guess, if you remove the to_s call, CSV.parse(csv_text) gives you an array of rows, just do csv.each do |row| after that.

EDOT: correct use of CSV.parse is:

csv_text = File.read(file_path)
CSV.parse(csv_text) do |row|
  ...
end

Upvotes: 1

Related Questions