7

So far I've managed to upload a file:

# In new.html.erb
<%= file_field_tag 'upload[file]' %>

And access the file in the controller

# In controller#create
@text = params[:upload][:file]

However, this gives me just the filename, not the file's contents. How do I access its contents?

I know this a jump, but once I can access the file's contents, would it all be possible to upload a folder and iterate through the files?

nathan
  • 1,456
  • 1
  • 15
  • 32

2 Answers2

8

Complete Example

Take, for example, uploading an import file containing contacts. You don't need to store this import file, just process it and discard it.

Routes

routes.rb

resources :contacts do 
  collection do
    get 'import/new', to: :new_import  # import_new_contacts_path

    post :import                       # import_contacts_path
  end
end

Form

views/contacts/new_import.html.erb

<%= form_for @contacts, url: import_contacts_path, html: { multipart: true } do |f| %>

  <%= f.file_field :import_file %>

<% end %>

Controller

controllers/contacts_controller.rb

def new_import
end

def import
  begin
    Contact.import( params[:contacts][:import_file] ) 

    flash[:success] = "<strong>Contacts Imported!</strong>"

    redirect_to contacts_path

  rescue => exception 
    flash[:error] = "There was a problem importing that contacts file.<br>
      <strong>#{exception.message}</strong><br>"

    redirect_to import_new_contacts_path
  end
end

Contact Model

models/contact.rb

def import import_file 
  File.foreach( import_file.path ).with_index do |line, index| 

    # Process each line.

    # For any errors just raise an error with a message like this: 
    #   raise "There is a duplicate in row #{index + 1}."
    # And your controller will redirect the user and show a flash message.

  end
end

Hope that helps!

Joshua

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
  • Just returning to think about this. I suppose it's not important to store the important file at all, even temporarily, because if something does go wrong with the import they'll have to re-import a new, fixed file anyway... – Joshua Pinter Nov 17 '17 at 19:39
5

In new.html.erb

<%= form_tag '/controller/method_name', :multipart => true do %>
   <label for="file">Upload text File</label> <%= file_field_tag "file" %>
   <%= submit_tag %>
<% end %>

In controller#method_name

uploaded_file = params[:file]
file_content = uploaded_file.read
puts file_content

see more for file upload in rails http://www.tutorialspoint.com/ruby-on-rails/rails-file-uploading.htm How to read whole file in Ruby?

Hope this will help you.

Community
  • 1
  • 1
suvankar
  • 1,548
  • 1
  • 20
  • 28
  • 3
    This gives me an error: `undefined method 'read' for "myfile.txt":String` – nathan May 03 '12 at 10:33
  • Try it with an :accept option, e.g. file_field_tag 'file', :accept => 'text/html' – novemberkilo May 03 '12 at 12:08
  • just install oen-uri using this command: $ sudo gem install open-uri – suvankar May 04 '12 at 15:35
  • @novemberkilo This will only allow me to add .html files, and I get the same undefined method error with .html files. Suvankar, I'd already installed and required open-uri in that controller. Any idea what else I could do? – nathan May 05 '12 at 07:56
  • 2
    if file upload work properly it can uplaod any kind of file. did you missed 'multipart=> true'? see more to http://www.tutorialspoint.com/ruby-on-rails/rails-file-uploading.htm – suvankar May 05 '12 at 11:29
  • $ [sudo] gem install carrierwave or add it in your gem file and then use bundle install. hope this will solve your problem – suvankar May 09 '12 at 09:16