Rails 3 - установить имя файла в response_to

17

Кажется, что это должно быть просто, но я не могу найти прямой ответ.

Я добавил csv mime-type и, похоже, работает, кроме , что загруженный файл всегда называется «report.csv».

В моем контроллере:

def report
  respond_to do |format|
    format.html
    format.csv do
      render :template => "summary/report.csv.erb",
             :filename => "foo" #doesn't work
    end
  end
end

Я думаю, что он использует средство рендеринга по умолчанию (я не реализовал альтернативный рендерер), но я не могу найти полные документы о доступных параметрах.

Нет ли что-то вроде опции «filename» или что-то, что я могу использовать? Есть ли лучший подход?

    
задан Grant Birchmeier 15.10.2012 в 20:48
источник
  • Возможно, это сообщение поможет: stackoverflow.com/questions/617055/... –  knownasilya 15.10.2012 в 21:40
  • Я видел это сообщение раньше, но я снова посмотрел на него из-за вашего комментария, и он нажал. У меня теперь есть рабочий ответ. Благодарю. –  Grant Birchmeier 15.10.2012 в 21:47

3 ответа

33

Я получил это, благодаря некоторой помощи этого .

format.csv do
  response.headers['Content-Disposition'] = 'attachment; filename="' + filename + '.csv"'
  render "summary/report.csv.erb"
end

Сначала вы задаете имя файла в заголовке ответа, затем вы вызываете render .

(Параметр шаблона для render не является обязательным, но в моем случае мне это нужно.)

    
ответ дан Grant Birchmeier 15.10.2012 в 21:50
источник
  • При попытке этого решения я получаю: неопределенную локальную переменную или «заголовки» метода. Любая идея, почему это может произойти? Откуда возникает ответ? –  deakolt 07.05.2013 в 02:01
  • хорошо ... Я получил это, чтобы работать, просто делая заголовки, а не response.headers –  deakolt 07.05.2013 в 02:39
  • @deakolt - я не могу полностью объяснить, откуда эта переменная ответа. Я думаю, что это предусмотрено ActionController :: Base. Может быть, он установлен блоком response_to? Не видя своего кода, я не могу догадаться, что другое. –  Grant Birchmeier 07.05.2013 в 18:09
  • On Rails 3.2 Мне нужно было установить заголовок после вызова render. Этот совет может потребоваться обновить. –  Mike Yockey 25.09.2014 в 19:42
  • На Rails 4 должно быть также после рендеринга, как сказал Йок. –  Jorge Sampayo 21.11.2014 в 16:19
Показать остальные комментарии
5

Вы можете передать имя файла send_data и разрешить ему обрабатывать заголовок Content-Disposition.

# config/initializers/csv_support.rb
ActionController::Renderers.add :csv do |csv, options|
  options = options.reverse_merge type: Mime::CSV
  content = csv.respond_to? :to_csv ? csv.to_csv : csv.to_s
  send_data content, options
end

# app/controllers/reports_controller.rb
respond_to do |format|
  format.html ...
  format.csv { render csv: my_report, filename: 'my_report.csv' }
end

Затем добавьте метод to_csv к my_report или передайте предварительно сгенерированную строку CSV.

    
ответ дан Flwyd 07.10.2013 в 04:51
источник
4

В качестве альтернативы вы можете использовать комбинацию send_data и render_to_string (поскольку у вас есть шаблон CSV).

def report
  respond_to do |format|
    format.html
    format.csv do
      send_data render_to_string(:template => "summary/report.csv.erb"),
             :filename => "foo"
    end
  end
end
    
ответ дан Slobodan Kovacevic 06.05.2014 в 12:24
источник
  • согласно документации ": filename - предлагает имя файла для использования браузером". Но это не работает. В Chrome, загружая файл, он устанавливает имя в конец маршрута, 'путь / download.csv' –  David Díaz Clavijo 23.10.2014 в 15:25