I am extremely new to rails and I have been looking all over on how to upload a file to a directory in Rails I found this Upload Files but I don't really understand it and I can't get it to work.
This is my View:
<%= form_for :upload, :html => {:multipart => true} do |f| %>
<%= f.file_field :my_file %>
<%= f.submit "Upload" %>
<% end %>
This is my Controller:
def upload
path = File.join("public/folder", upload["datafile"].original_filename)
File.open(path, "wb") { |f| f.write(upload["datafile"].read) }
end
I have also tried the Upload file section of Rails Guides
It says Stack level too deep, can somebody please help and try and explain this to me as simply as possible?
Thanks
uploading in ROR similar
name = upload['datafile'].original_filename
directory = "public/data"
# create the file path
path = File.join(directory, name)
upload_file = File.new(upload['datafile'], "rb").read
# write the file
File.open(path, "wb") {|f| f.write(upload_file) };
use this it may be help you...........
Related
Well, I'm searching this for a couple of days and I really couldn't find a solution. I'm trying to send multiple files and store it locally(or maybe in the future in a s3 bucket) and save also to the db.
I noticed that I'm getting a string instead of the file itself!
I'm using rails 5.1 and ruby 3.2
Here is my code:
Controller:
all_files = params[:files]
all_files.each do |fil|
File.open(Rails.root.join('public', 'uploads', all_files.original_filename), 'wb') do |filea|
filea.write(all_files.read)
end
end
form
<%= form_for #docs, :url => docs_create_path, :html => { :multipart => true } do |f| %>
<%= f.file_field :files, :multiple => 'multiple', :name => 'files[]'%>
<%= f.submit( "Upload file" ) %> <% end %>
Common errors: undefined method `original_filename' for #Array:0x0000000006aeb338>
there is small mistake here replace all_files.orginal with file.orginal
all_files = params[:files]
all_files.each do |file|
File.open(Rails.root.join('public', 'uploads', file.original_filename), 'wb') do |temp_file|
temp_file.write(temp_file.read)
end
end
I'm building an app where users can upload csv files to load data onto our platform. I have a form that lets a user upload a file and a method that saves the file in a specified folder. I want to append the user_id to the filename. How would I do that?
my form:
<%= form_tag import_listings_path, multipart: true do %>
<%= file_field_tag :my_file %>
<%= hidden_field_tag :user_id, current_user.id %>
<%= submit_tag "Import CSV" %>
<% end %>
my controller method:
def import
tmp = params[:my_file].tempfile
file = File.join("public", params[:my_file].original_filename)
FileUtils.cp tmp.path, file
end
For example, if a user uploads test.csv and their user_id is 20. I want the new filename to be test20.csv
A bit ugly but this should do the job... basically extracting the file extension (obtaining the last string after the '.'), appending the user id and adding the extension back:
x = params[:my_file].original_filename.split('.')
x[x.length - 2] += params[:user_id]
file = File.join("public", x.join('.'))
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 have a Rails 4 app that uses Carrierwave and Fog to upload files to Amazon S3. The servers the app uses is Nginx and Thin.
The problem I'm having is when uploading files over 5mb.
I've tried searching everywhere for a way to get it working, I've tried CarrierwaveDirect and still can't get it to work.
Here is my Carrierwave config:
config.fog_directory = 'aws-bucket-name'
config.fog_public = false
config.fog_attributes = { multipart_chunk_size: 5242880 }
config.max_file_size = 200.megabytes # CarrierwaveDirect option
Here are the controller actions:
def new
#file = DownloadFile.new
end
def create
#file = DownloadFile.new
#file.file = params[:download_file][:file]
if #file.save
redirect_to downloads_path
else
render :new
end
end
And the form:
<%= form_for #file, multipart: true do |f| %> <!-- even tried with `multipart` wrapped in `html: {}` -->
<%= f.label :file %>
<%= f.file_field :file %>
<%= f.button t(:upload) %>
<% end %>
I can upload small files just fine, but when it comes to files that are over 5mb, the form just redisplays. No errors, no errors in the logs, nothing.
With Carrierwave Direct it looks like you would need to setup the form slightly differently (as it would need to set the url to one on S3, rather than on your own server). If you are dealing with large files this may be preferable as large files would otherwise tie up a process for an extended time. To make that work it looks like you'll want to use the direct_upload_form_for helper method instead of plain form_for, something like:
<%= direct_upload_form_for #uploader do |f| %>
<%= f.file_field :avatar %>
<%= f.submit %>
<% end %>
For a bit more detail on that, see: https://github.com/dwilkie/carrierwave_direct#rails
I'd like to make a simple file uploader using tag_form on Rails 3.2.8.
But when I try to submit a image file, I get an error saying
Error Message (when I try to submit a image file)
NoMethodError in CoursesController#attachment
undefined method `original_filename' for "2012-03-02 21.53.55.jpg":String
----- BEGIN P.S.(20121216 19:32) -----
or
Error Message (when I added ":multipart => true" on show.html.erb)
Encoding::UndefinedConversionError in CoursesController#attachment
"\xFF" from ASCII-8BIT to UTF-8
----- END P.S. -----
It seems that the program consider the file as String?
There might be some problem in the view file.
I'd appreciate it if you help me with this problem. Here's my codes.
app/view/show.html.erb
<%= form_tag(attachment_course_path, :action=>'attachment') do %>
<div class="field">
<%= label_tag :file %>
<%= file_field_tag :file %>
</div>
<div class="actions">
<%= submit_tag 'Submit' %>
</div>
<% end %>
app/controller/courses_controller.rb
def attachment
t = Time.now.strftime("%Y%m%d%H%M%S")
uploaded_io = params[:file]
File.open(Rails.root.join('public', 'upload', uploaded_io.original_filename), 'w') do |file|
file.write(uploaded_io.read)
end
end
config/routes.rb
resources :courses, :only => [ :show ] do
member do
post :attachment
end
end
seems the form is not sending files with request. you need to set :multipart => true in form_tag.
The problem seems similar to RoR upload Undefined encoding conversion
After setting :multipart => true in form_tag you need to open the file in binary mode ('wb' instead of 'w'):
app/controller/courses_controller.rb
...
File.open(Rails.root.join('public', 'upload', uploaded_io.original_filename), 'wb') do |file|
file.write(uploaded_io.read)
end
...