Вопрос

Я создал файл в каталоге TMP со следующим кодом контроллера:

  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

Это создает файл, который я хотел в каталоге TMP, то, что я хочу сделать, это заставить пользователя загрузить этот файл.

На моей локальной машине файл сохраняется на пути, как:

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

И на живом сервере этот URL будет совсем другим.

Мне было интересно, как заставить пользователя загрузить это xxxx.html?

PS, если я положу ...

redirect_to file_path

... На контроллере это просто дает мне маршрут, который не найден.

Ваше здоровье.

Это было полезно?

Решение

Взглянуть на послать файл метод Это выглядело бы примерно так:

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

: Disposition => 'Attachment' заставит браузер загружать файл вместо его рендеринга. Установите его на «встроенный», если хотите, чтобы он загрузился в браузере. Если Nginx находится перед вашим приложением Rails, вам придется изменить конфигурацию вашей среды (т.е. Environments/Production.rb):

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

Другие советы

Легко запутать пути файлов с URL -адресами, но это важное различие. Что имеет URL -пути /a/b.txt фактически расположен в системном пути #{Rails.root}/public/a/b.txt Таким образом, вам может потребоваться решить это, генерируя оба в тандеме.

Вот как вы можете решить это:

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

Вы не можете перенаправить ресурс, который не раскрывается через ваш веб -сервер, и, как правило, только вещи в public/ устанавливаются таким образом. Вы можете включить дополнительные пути, если вы настраиваете свой сервер соответственно.

Вы также можете поставить весь этот процесс, просто отобразив ответ как загружаемое встроенное вложение, если вы предпочитаете:

render(:action => :show, :layout => nil, :content_type=> 'application/octet-stream')
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top