2012-10-08 18 views
8

En mi aplicación Ruby on Rails, tengo un botón de carga de archivos simple que estoy tratando de reemplazar con un cuadro de arrastrar y soltar usando las API File/FileReader en HTML5 , usando this tutorial específicamente. Como es así, uso un script de Ruby para subir el archivo a mi carpeta pública/de datos. No estoy seguro de cómo integrar el script de arrastrar y soltar con eso. Mi idea era crear el botón de carga de archivos que ya había ocultado, y usar Javascript para establecer su valor en la ruta de la imagen arrastrada y soltada cuando el usuario intenta enviarla.Carga de archivos HTML5 arrastra y suelta con Ruby on Rails

Sin embargo, cuando intento enviar me sale el error:

File name too long - public/data/data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QMtaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNj....

porque el nombre de archivo de almacenamiento temporal proporcionado por HTML 5 es simplemente demasiado tiempo, supongo.

Probé la concatenación de la cadena en los primeros 60 caracteres y luego se lo di el error:

No such file or directory - public/data/data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAA

En cualquier caso, el archivo no está siendo añadido a public/data carpeta.

Mi 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 

y JS:

$("#submit input").click(function() { 
    $("#uploadfile").val($("#preview").attr("src")); 
}); 
+1

que debería recomendar esta joya: http://blueimp.github.com/jQuery-File-Upload/ Siga el tratamiento durante un intento, creo la implementación es muy directa. Solo eche un vistazo a la documentación de ruby. –

+0

Es increíble, pero esto no es una joya, es un plugin jquery. El wiki [https://github.com/blueimp/jQuery-File-Upload/wiki] se refiere a muchos ejemplos de rubíes y una gema, [https://github.com/tors/jquery-fileupload-rails] – AndreDurao

Respuesta

0

El punto es de uso params [: uploadfile] como valor de nombre es innecesario, si quiere una clave única que puede usar SecureRandom.uuid.

0

Parece que el problema es que está enviando el archivo como una URL de datos codificada en Base64, lo cual está bien, pero el nombre de archivo no coincide con cuando se realiza la POST en el servidor. Es posible que desee extraer el nombre de archivo antes de convertir el archivo a una URL de datos para que pueda enviarlo junto con el archivo en los parámetros. O cree un nuevo nombre de archivo (UUID) como sugirió Madao.

Esto debería al menos arreglar el problema de nombre de archivo:

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