Multiple text file upload Rails 3 - ruby-on-rails

My app is currently set up to upload and parse a single file at a time:
Form in my View:
<%= form_tag({:controller => "#{controller}", :action => "import"}, :multipart => true) do %>
<em>Upload a tab-separated .txt file.</em>
<%= file_field_tag :file %>
<br/>
<%= submit_tag "Import Data", :class => "btn btn-link"%>
<% end %>
My Controller:
def import
file = params[:file]
RatingSet.generate_uploaded_rating_set({:conditions => "data_1", :file => file})
redirect_to "/index", :flash => { :notice => "Successfully Uploaded." }
end
I then parse and add the file contents in a method in my RatingSet model.
How can I upload multiple text files to different controllers? I would like the add about 4 form upload fields, and allow the user to choose which controller they would like to upload the form to. Ideally I would like to user JS to add new form fields, for as many forms the user would like to upload, however 4 fields would suffice for now.

Related

Controllers and downloading files with 'send_data'

I can create both xl and csv files formats fine, and would like to create a download link for them within a form.
A user can generate a search for records using this form
=simple_form_for :guestlist_booking_search, controller: 'guestlist_bookings_controller', action: 'index', method: :get do |f|
%fieldset
%legend Guestlist Booking Search
= f.input :lastname
= f.input :start, as: :string, class: "form-control auto_picker1", :input_html => { :class => 'auto_picker1', value: guestlist_booking_search.start.strftime('%d-%m-%Y %H:%M') }
= f.input :finish, as: :string, class: "form-control auto_picker2", :input_html => { :class => 'auto_picker2', value: guestlist_booking_search.finish.strftime('%d-%m-%Y %H:%M') }
= f.submit "Submit"
= f.submit "Download CSV", name: "download_csv"
So the form has two submit buttons, I would like one to process the search and display the results, and the other to process the search and begin downloading an csv file.
So in my index action I have this
def index
if params[:download_csv]
respond_to do |format|
format.html
format.csv { send_data #guestlist_bookings.to_csv }
end
end
end
the guestlist_bookings variable is set in a before block (generating and displaying the search works fine ).
What I can't seem to work out is how to get the file to begin downloading. Currently there is no response from the .xls block. From what I can understand the 'send_data' function is what is used to start a download from the controller.
I think your problem is that it's evaluating the format.html block, not the format.csv block, because you haven't told it that the required format is csv.
Try changing your first line like so - this uses a named route which is nicer for various reasons:
=simple_form_for :guestlist_booking_search, url: guestlist_bookings_path(format: "csv"), method: :get do |f|
Ok so the answer I found here
= f.submit "Go"
= f.submit "CSV", value: :csv, name: :format
basically you need to set the format before the form runs.

Rails - Upload and parse multiple CSV files

Im trying to upload and parse multiple CSV files. What I have so far:
My View
<h3>Upload multiple files</h3>
<%= form_tag({:controller => "multi_uploader", :action => "import"}, :multipart => true) do %>
<em>Upload a tab-separated .txt file to generate new rating sets.</em> <hr/>
<%= file_field_tag :file_1 %>
<hr/>
<%= file_field_tag :file_2 %>
<hr/>
<%= file_field_tag :file_3 %>
<hr/>
<%= file_field_tag :file_4 %>
<hr/>
<%= file_field_tag :file_5 %>
<hr/>
<%= file_field_tag :file_6 %>
<hr/>
<%= submit_tag "Import Data", :class => "btn btn-link"%>
<% end %>
My Controller:
def import
unless params[:file_1].nil?
file_1 = params[:file_1]
RatingSet.multi_uploader(file_1)
end
unless params[:file_2].nil?
file_2 = params[:file_2]
RatingSet.multi_uploader(file_2)
end
unless params[:file_3].nil?
file_3 = params[:file_3]
RatingSet.multi_uploader(file_3)
end
unless params[:file_4].nil?
file_4 = params[:file_4]
RatingSet.multi_uploader(file_4)
end
unless params[:file_5].nil?
file_5 = params[:file_5]
RatingSet.multi_uploader(file_5)
end
unless params[:file_6].nil?
file_6 = params[:file_6]
RatingSet.multi_uploader(file_6)
end
redirect_to "/multi_uploader", :flash => { :notice => "Successfully Uploaded." }
end
My Model method to import file:
def self.multi_uploader(file)
upload = File.open(file.path)
#Parse file and save data to db.
end
In my multi_uploader method, I parse out a key (from the file) for which category the file is supposed to be uploaded to. Everything works as expected when I upload a single file, however if I upload multiple files, the contents of all files are being saved for to a single category, rather than multiple categories. Its as if all files are being treated as a single file, rather than n individual files. What can I change to upload each file individually?
Well, as far as I see. This behavior shouldn't actually be happening. I would suggest another way of doing this code, since it's looking a bit polluted.
def import
(1..x).each do |i| #with x being the max number of files uploaded at the same time
RatingSet.multi_uploader(params["file_#{i}".to_sym])
end
redirect_to "/multi_uploader", :flash => { :notice => "Successfully Uploaded." }
end
Either way, this shouldn't solve your problem. I can't tell why this is happening to be honest.
UPDATE:
Have you considered using: <%= f.file_field :file, :multiple => true %> instead of mutiple file_tags?

Create an upload controller action for Rails app

I'm making a Rails app, and want to add an upload feature with allows users to upload multiple entries at once through an Excel spreadsheet as opposed to entering one entry at a time.
Ideally, I was hoping to add a separate Upload/Submit portion to the bottom of the new.html.erb file (the bold portion being the Upload HTML.erb):
...
<div class="actions">
<%= f.submit %>
</div>
<% end %>
**<div class="field">
Or Upload Multiple Entries <br />
<%= form_tag({:action => :upload}, :multipart => true) do %>
<%= file_field_tag 'multi_doc' %>
<% end %>
</div>**
Here is my routes.rb file:
Dataway::Application.routes.draw do
devise_for :users
resources :revenue_models do
get 'upload', :on => :collection
end
root :to => "home#index"
end
And my revenue_models_controller (haven't developed the action at all yet, now just a redirect):
...
def upload
redirect_to revenue_models_path
end
I have followed the rails guides for Uploading files as well as for Routing files and I keep getting an error when I attempt to open the /new view I have modified:
Routing Error
No route matches {:action=>"upload", :controller=>"revenue_models"}
Try running rake routes
When I run rake route, I get an entry for the upload action:
upload_revenue_models GET /revenue_models/upload(.:format) revenue_models#upload
In the end, what I would like to do is upload an excel file with multiple entries, parse it, and conditionally add each data row to my database, which I was under the impression I could specify in the upload action. Please help!
Please use form_for instead form_tag.
Second What is multi_doc is a field/attribute of revenue_model?. I guess is a field/attribute of revenue_model.
Third, Where is your instance variable revenue_model in the form?
Fourth, You have to create first a instance variable of your Model, on your action/controller where you are showing the form, for example #revenue_model = RevenueModel.new.
After try this code:
<%= form_for(#revenue_model, :method => :get, :html => {:multipart => true}, :url => { :controller => "revenue_models", :action => "upload"})) do |f| %>
<%= f.file_field :multi_doc %>
<%= f.submit :id => "any_id" %>
<% end %>
The question is very confusing, trying to clarify your question specifying the name of your actions and the names of the files in your views.
Regards!

Rails form_for with file_field and remote => true and format => :js

I am submitting a form_for with a file_field in it. When the form is submitted with a post, the controller responds with a .js file which will be executed.
The file_field is optional.
When I upload a file, the js file is opened in a new document (as a simple text file) and the js is not executed. When I don't upload any file, the response div is updated. I want the update success to be notified in the response div or a failure message independent of the file upload.
May be this is done for some security reasons? Is there some workaround for people who want to be able to do this?
Roughly,
Form partial _action.html.erb:
<div id="response"></div>
<%= form_for ... :remote => true, :url => {..., :format => :js} do |f| %>
...
<%= f.file_field :name %>
<% end %>
Controller::action
if not request.post?
render :partial => 'controller/action'
return
else
#response = "save was successful";
# renders the action.js.erb
end
action.js.erb:
$("#response").html("<%= #response %>");
Try to use remotipart gem https://github.com/JangoSteve/remotipart
Following Solution work for me
$('.sales_application_form').submit(function() {
$(this).ajaxSubmit();
return false;
});

Problem using 'responds_to_parent' with an iframe and AJAX to upload a file

I followed instructions from the "AJAX file uploads in Rails using attachment_fu and responds_to_parent" article. In my case I am using Ruby on Rails 3 and Paperclip.
What I made is the following:
I have installed the 'respons_to_parent' plugin running this command in the Terminal:
rails plugin install git://github.com/itkin/respond_to_parent.git
After installing, I restart Apache.
In my view I have:
<%= form_for(#user, :html => { :multipart => true, :target => 'upload_frame' }) do |f| %>
<%= f.file_field :avatar %>
<%= f.submit "Submit" %>
<% end %>
<div id="test">Here is a test</div>
<div id="stuff">Here is some stuff</div>
<iframe id='upload_frame' name="upload_frame" style="width:1px;height:1px;border:0px" ></iframe>
In my controller I have
def action
respond_to do |format|
...
format.js {
responds_to_parent do
render :update do |page|
page.replace_html :test, "This is the resulting test"
page << "alert($('stuff').innerHTML)"
end
end
end
end
end
Trying to submit the form, all about the file uploading works (Paperclip handle correclty files, ...) and in the log file there aren't errors.
The only thing that isn't working is the AJAX part. In the example
page.replace_html :test, "This is the resulting test"
page << "alert($('stuff').innerHTML)"
don't update the page (BTW: where these should have effect? in the "main view" or in the "iframe view"?). It doesn't work also if I try to delete the 'respons_to_parent' statement or if I put them in the 'action.js.rjs' file.
Where I am wrong?
SOLVED
I had forgotten to add :url => users_account_path +. "js". So the view become:
<%= form_for(#user, :url => users_account_path +. "js", :html => { :multipart => true, :target => 'upload_frame' }) do |f| %>

Resources