I'm trying to upload a CSV file(without headers) to a form in Rails, and then change my database based on that file's contents.
Now, the problem I'm having is that I know my routes must be correct, because I'm able to get to the correct method...but, my #imported variable is saying it is nil even when I upload a file.
Is there any help I can get for this? This will be my first file upload in rails, so we can cross this milestone together...
Here is the form in my view, mapped to the #ship action:
<%= form_for #import, :url => {:action => "ship", :controller => "imports"} do |f| %>
<%= f.file_field :import %>
<%= f.submit %>
<% end %>
And here is the corresponding method in my controller:
def ship
#import = CSV.read(params[:file])
#import.each do |i|
Product.ship(#import[i][0]) #I believe the #read method imports
end #CSV files as an array of arrays
redirect_to "/" #But I have yet to get past the
end #first line, so I'm unsure
Sergio Tulentsev is right. You need to use params[:import][:import]. The first import being the name of your resource (comes from form_for #import, the second import being the field name (coming from f.file_field :import).
More info at http://guides.rubyonrails.org/form_helpers.html#uploading-files
Related
I have created simple application form and i was trying to upload file and send it as email attachment. And i did it with this approach:
class ApplyController < ApplicationController
def prepare_email_content
ApplyMailer.with(params).apply.deliver_now
end
end
class ApplyMailer < ApplicationMailer
def apply
#company = Company.find(params[:company_id])
#candidate = params[:name]
#candidate_mail = params[:email]
#email = #company.email
attachments[params[:cv].original_filename] = params[:cv].read
mail to: #email, subject: 'Hello'
end
end
<h1>APPLY</h1>
<%= form_tag(apply_path, method: :post, multipart: true) do %>
<%= label_tag(:name, "First and last name:") %>
<%= text_field_tag(:name) %>
<%= label_tag(:email, "Email:") %>
<%= text_field_tag(:email) %>
<%= hidden_field_tag :company_id, params[:company_id] %>
<%= file_field_tag 'cv' %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<%= link_to 'All offers', hello_path %>
Everything was working fine - i have tested application and it was fine. Then i have developed my application and when i come back to testing i started getting this error:
On the way i have installed some gems and updated few of them. I was checking out to commit where this feature was working and it is. But i'm not able to find any differences in my code. There were some changes in /.idea folder but i don't know if any of this files could trigger this issue.
I'm using rails 6.0.3 and ruby 2.5.8
EDIT
I can see that there is a problem inside called methods. Looks like it cannot find #sort_order value and it sets data value as nil. But i have no idea how to change working of this.
Replace the line you're attaching the file with
attachments["#{params[:cv].original_filename}"] = File.read(params[:cv].path)
Even though you're not saving the file, there is a still a local path to grab the file from.
Also, you should really consider passing the parameters to the mailer from the controller, rather than passing params in its entirety. That way if the information or format of the upload is incorrect, you can redirect back to the form and bypass sending the email.
All I'm trying to do is parse a file with Rails, but I can't for the life of me pass it through to my controller. I can't even get the file name or path to show up in the submitted params.
My form:
<%= form_tag({url: upload_path}, method: :patch, multipart: true) do %>
<%= file_field(:user, :csv, :multiple => false, class:"file-field") %>
<%= submit_tag 'Submit', class:"btn" %>
<% end %>
My controller:
def upload
file = params[:user][:csv] #params[:user] is nil
#parse file
end
According to the rails docs, I thought the file should be contained in params[:user][:csv], but I must be misinterpreting something because params[:user][:csv] is nil, and neither "user" or "csv" show up anywhere in the params.
I want to be able to get the file path, and then using that, parse the file. What am I doing wrong?
Use this for file_field_tag
<%= file_field_tag('user["csv"]', :multiple => false, class:"file-field") %>
Options should go after name and I don't understand what is :csv in that case if :user is name
I am using Carrierwave for file uploading and have got the following form, which allows me to submit several files:
<%= form_tag load_patterns_contacts_path, multipart: true, multiple: true do %>
<%= file_field_tag 'qqfile[]', id: "upload_pattern", multiple: true %>
<%= submit_tag "Load", id: "save_pattern", :class => 'btn btn-primary btn-success', multiple: true%>
<% end %>
Here is the code in my controller, which load submited files to the server:
#uploader = EmailPatternsUploader.new
params[:qqfile].each do |p|
tempfile = open(p.original_filename)
puts tempfile
#uploader.store!(tempfile)
end
redirect_to contacts_path
flash[:success] = "Uploaded successfully."
It works fine, if filename looks like "text.xlsx", "image.jpg" etc. But if it is contains special symbols like "_partial.html.erb" then I have got Errno:ENOENT (No such file or directory - _partial.html.erb)
I have tried to add
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\_\-\+]/
in my carrierwave.rb initializer, but it gives no result.
Thanks in advance for help!
UPDATE:
I have understood, that the problem not in special symbol "_", but in the fact, that samples I am trying to upload contains two dots ("."). I think I need to modify regular expression in order to avoid two dots
UPDATE:
I am sorry for the last comments. I have understood, that the matter not in special symbols at all and not in a name of file. The problem that i can upload files only from {Rails.root} path. If I choose another directory, I have got aforementioned error and cannot upload a file. How can I configure Carrierwave path directory?
Finally find an answer on my question.
The error was in these strings of code:
params[:qqfile].each do |p|
tempfile = open(p.original_filename)
puts tempfile
#uploader.store!(tempfile)
end
I have understood, that I need to pass an object ActionDispatch::Http::UploadedFile in Carrierwave store! method. Thats why the mentioned above code shall be the following:
params[:qqfile].each do |p|
puts p.original_filename
puts p
#uploader.store!(p)
end
==================================================================================
Hope someone find this solution for multiple file uploading with Carrierwave and without JQuery useful.
1) Create an uploader, using Carrierwave.
rails g uploader EmailPatterns
2) Create a custom action for your controller (watch Railscast#35 and Railscast#38 to make it clear) and put there something like this (load_patterns in my case):
def load_patterns
#uploader = EmailPatternsUploader.new
params[:qqfile].each {|p| #uploader.store!(p)}
redirect_to contacts_path
flash[:success] = "Uploaded successfully"
end
To make it work you need to specify custom route(config/routes.rb) for your action:
resources :contacts do
collection { post :load_patterns}
end
and to create a form, where you will get params with your uploading files (see p.3)
3) Create form, where you need to specify the option multiple:true in order to allow user to select several files to load (param name with [ ] is a necessary requirement, because we are loading several files) :
<%= form_tag load_patterns_contacts_path, multipart: true, multiple: true do %>
<%= file_field_tag 'qqfile[]', id: "upload_pattern", multiple: true %>
<%= submit_tag "Load", id: "save_pattern", :class => 'btn btn-primary btn-success', multiple: true%>
<% end %>
Then your custom action will work.
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!
I'm uploading a plain text file and I'd like to use the text within as the parameters for a new object. Here's my attempt so far, in views/scans/new.html.erb:
<h1>New scan</h1>
<%= form_for :file_upload, :html => {:multipart => true} do |f| %>
<p><%= f.file_field :raw %></p>
<p><%= f.submit "Upload" %></p>
<% end %>
raw is a text attribute of the scan model. This yields the error:
Routing Error
No route matches [POST] "/scans/new"
Try running rake routes for more information on available routes.
I can tell from Google that I need to File.read() but I don't know where I would do it.
in model
def raw= (file)
File.open(file,"r") do |f|
self.your_atrribute = f.readlines.join("")
end
end