akhil
akhil

Reputation: 31

How to parse the contents of a uploaded file in RoR

I am new to Rails. In my project where users have to upload a file, I store it then I have to parse the file contents and show it in new form.

I have successfully done the file uploading portion, now how should I read the contents of it?

Upvotes: 3

Views: 2757

Answers (3)

Joshua Pinter
Joshua Pinter

Reputation: 47471

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, on: :collection      # 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 others!

JP

Upvotes: 0

John Topley
John Topley

Reputation: 115312

You can open files and read their contents in Ruby using the File class, as this simple example demonstrates:

# Open a file in read-only mode and print each line to the console
file = File.open('afile.txt', 'r') do |f|
  f.each do |line|
    puts line
  end
end

Upvotes: 2

Lars Haugseth
Lars Haugseth

Reputation: 14881

Try something like this:

upload = params[:your_upload_form_element]
content = upload.is_a?(StringIO) ? upload.read : File.read(upload.local_path)

Very small files can be passed as strings instead of uploaded files, therefore you should check for that and handle it accordingly.

Upvotes: 5

Related Questions