In my Ruby on Rails app, I have a simple file upload button that I'm trying to replace with a drag and drop box using the File/FileReader APIs in HTML5, using this tutorial specifically. As is, I use a Ruby script to upload the file to my public/data folder. I'm not sure how to integrate the drag-and-drop script with that. My idea was to make the file upload button I had already hidden, and use Javascript to set its value to the path of the drag-and-dropped image when the user tries to submit.
However, when I try to submit I get the error:
File name too long - public/data/data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QMtaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNj....
because the temporary file storage name given by HTML5 is just too long, I guess.
I tried concatenating the string to the first 60 characters and then it gave the error:
No such file or directory - public/data/data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAA
In any case, the file is not getting added to public/data
folder.
My HTML:
<%= form_tag( { :action => 'create' }, :multipart => true ) %>
<div id="dropbox"><span id="droplabel">Drop file here...</span></div>
<img id="preview" alt="[ preview will display here ]" />
<%= hidden_field_tag :uploadfile, :id => "uploadfile", :name => "uploadfile" %>
<br /><br />
<div id="submit">
<%= submit_tag( "Upload file" ) %>
</div>
Ruby:
def create
name = params[:uploadfile]
directory = "public/data"
path = File.join(directory, name)
File.open(path, "wb") { |f| f.write(params[:uploadfile].read) }
@project = Project.new({:filename => name, :location => path})
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: 'Project was successfully created.' }
format.json { render json: @project, status: :created, location: @project }
else
format.html { render action: "new" }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
and JS:
$("#submit input").click(function() {
$("#uploadfile").val($("#preview").attr("src"));
});
The problem looks like you are sending the file as a Base64 encoded Data URL, which is fine, but the filename doesn't go along with it when you POST to the server. You may want extract the filename before converting the file to a Data URL so you can send it along with the file in the params. Or, create a new filename (UUID) like Madao suggested.
This should at least fix your filename problem:
def create
##
file = params[:uploadfile]
name = params[:filename] || SecureRandom.uuid
##
directory = "public/data"
path = File.join(directory, name)
File.open(path, "wb") { |f| f.write(file.read) }
@project = Project.new({:filename => name, :location => path})
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: 'Project was successfully created.' }
format.json { render json: @project, status: :created, location: @project }
else
format.html { render action: "new" }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With