简体   繁体   中英

Rails - Can't import data from CSV file

I am trying to import data from a CSV file, I don't want to save the file. I have found a similar question here: Ruby on Rails - Import Data from a CSV file

However, when I try and use this solution I get an error.

My Form is as follows:

Import a CSV file
<%= file_field_tag :file %>

<div class="actions form-group" id="button_text">
<p>
<%= button_tag(type: 'submit', class: "btn btn-primary button-submit") do %>
Submit
<% end %>

On the new page the submission of this form calls the create action, the create action then calls the line:

Product.import(params[:file])

I have the following import method in my model:

def self.import(myfile)
    require 'csv'    

    csv_text = File.read(myfile)
    csv = CSV.parse(csv_text, :headers => true)
    csv.each do |row|

    end
end

where 'myfile' is params[:file].

I am aware I am not doing anything with the data yet. I am getting an error with line csv_text = File.read(myfile) which is: No such file or directory @ rb_sysopen - X.csv

When looking for a solution I have seen .path is used. If i change this line to csv_text = File.read(myfile.path) I get the error: undefined method `path' for "X.csv":String

Can anybody help? I feel like I must be very close to a solution but I just keep going round and round between these two errors. Is it possible to get the data from the csv without saving it first?

Thanks for your time

you can do something like this way .html.erb

<%= form_for(<object>, url: <path>, method: :post, remote: :true, html: {
  multipart: true, }) do |f| %>
    <input type="file" name="file_batch_upload"  accept=".csv />
<% end %>

//Define that function

def self.import(file)
    require 'csv'    

    csv_text = File.read(file.tempfile)
    csv = CSV.parse(csv_text, :headers => true)
    csv.each do |row|
     //row["name"]
    end
end

The most important thing to remember with file uploads is that the rendered form's encoding MUST be set to multipart/form-data . I guess you have that maintained.

<%= form_tag({action: :upload}, multipart: true) do %>
  <%= file_field_tag 'file' %>
<% end %>

Now in controller you will have access to IO object via params . The object in the params hash is an instance of a subclass of IO.

The object will have an original_filename attribute containing the name the file had on the user's computer and a content_type attribute containing the MIME type of the uploaded file.

You can either move the temporary file to some dir in your public directory or simple use and throw away.

def upload
  uploaded_io = params[:file]

  # Moving the file to some safe place; as tmp files will be flushed timely
  File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'wb') do |file|
    file.write(uploaded_io.read)
  end
end

for you, you can leverage the tempfile attribute in the IO object. The actual file is accessible via the tempfile accessor, though some of its interface is available directly for convenience.

So, this should work

...
csv_text = File.read(file.tempfile)
...

Update

> uploaded_io = params[:file]
=> #<ActionDispatch::Http::UploadedFile:0x007f4154fe9a38
 @content_type="application/pdf",
 @headers="Content-Disposition: form-data; name=\"file\"; filename=\"3423loadshedding.pdf\"\r\nContent-Type: application/pdf\r\n",
 @original_filename="3423loadshedding.pdf",
 @tempfile=#<File:/tmp/RackMultipart20160421-14883-1lv0qtq.pdf>>

[2] pry(#<PostsController>)> uploaded_io.tempfile
=> #<File:/tmp/RackMultipart20160421-14883-1lv0qtq.pdf>

> uploaded_io.tempfile.class
=> Tempfile

For Error

ProductsController#upload No such file or directory @ rb_sysopen - /<path to my app>/public/uploads/X.csv 

You need to first create the folder public/uploads

$ mkdir public/uploads

Now try; the file should be moved. This is how Paperclip and Carrierwave manage uploaded files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM