Pregunta

He creado un archivo en el directorio TMP con el siguiente código del controlador:

  def download
    file_path = "#{RAILS_ROOT}/tmp/downloads/xxx.html"
    data = render_to_string( :action => :show, :layout => nil )
    File.open(file_path, "w"){|f| f << data }
    flash[:notice] = "saved to #{file_path}"
  end

Esto crea el archivo que quería en el directorio TMP, lo que quiero hacer es obligar al usuario a descargar ese archivo.

En mi máquina local, el archivo se guarda en ruta como:

/Users/xxxx/Documents/Sites/xxxx/Website/htdocs/tmp/downloads/xxxx.html

Y en el servidor en vivo, esta URL será algo totalmente diferente.

Lo que me preguntaba es cómo obligar al usuario a descargar este xxxx.html.

PD: si pongo un ...

redirect_to file_path

... En el controlador, solo me da una ruta que no se encuentra.

Salud.

¿Fue útil?

Solución

Echa un vistazo al enviar archivo método. Se vería algo así:

send_file Rails.root.join('tmp', 'downloads', 'xxxxx.html'), :type => 'text/html', :disposition => 'attachment'

: disposition => 'Archivo' obligará al navegador a descargar el archivo en lugar de representarlo. Configure en 'en línea' si desea que se cargue en el navegador. Si NGINX está frente a su aplicación Rails, deberá modificar su configuración de entorno (es decir, entornos/producción.rb):

# For nginx:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

Otros consejos

Es fácil confundir rutas de archivos con URL, pero es una distinción importante. ¿Qué tiene un camino de URL de /a/b.txt en realidad está ubicado en la ruta del sistema #{Rails.root}/public/a/b.txt Por lo tanto, es posible que deba abordar esto generando ambos en conjunto.

Así es como puede abordar eso:

def download
  base_path = "downloads/xxx.html"

  system_path = File.expand_path("public/#{base_path}", Rails.root)
  url_path = "/#{base_path}"

  File.open(file_path, "w") do |f|
    f.puts render_to_string(:action => :show, :layout => nil)
  end

  flash[:notice] = "saved to #{base_path}"

  redirect_to(url_path)
end

No puede redirigir a un recurso que no esté expuesto a través de su servidor web, y generalmente solo cosas en public/ están establecidos de esta manera. Puede incluir rutas adicionales si configura su servidor en consecuencia.

También puede pasar todo este proceso todo simplemente renderizando la respuesta como un archivo adjunto en línea descargable, si lo prefiere:

render(:action => :show, :layout => nil, :content_type=> 'application/octet-stream')
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top