#ruby-on-rails #ruby-on-rails-6
Вопрос:
У меня есть представление, которое позволяет пользователю выбрать группу записей для экспорта в файл CSV.
После того, как пользователь выберет набор записей и отправит форму с информацией, CSV будет правильно сгенерирован и возвращен, но вместо того, чтобы спросить пользователя, где сохранить файл, ничего не произойдет. После проверки запроса в браузере я обнаружил, что данные присутствуют в полезной нагрузке ответа в виде необработанного CSV. Как я могу заставить браузер вместо этого показывать диалоговое окно сохранения?
Представление имеет форму, содержащую список записей, и каждая запись может быть выбрана (с помощью флажка) для экспорта.
<%= form_with url: export_to_csv_admin_properties_url, multipart: true do |form| %>
<table class="table is-striped">
<thead>
<tr>
<th><%= sortable "id" %></th>
<th><%= sortable "city" %></th>
<th>To export</th>
</tr>
</thead>
<tbody>
<% @properties.each do |property| %>
<tr>
<td><%= property.id %></td>
<td> <%= property.city %> </td>
<td><%= check_box("export", property.id) %></td>
</tr>
<% end %>
</tbody>
</table>
<%= form.submit "Export" %>
<% end %>
Контроллер правильно получает данные и вызывает класс, ответственный за построение строки CSV:
def export_to_csv
ids_to_export = params[:export].select { |_key, value| value == '1' }.keys
properties = Property.find(ids_to_export)
csv_data = CsvService.export_properties(properties)
send_data csv_data, filename: "exported_properties.csv", type: 'text/csv'
end
Комментарии:
1. @dbugger —
csv_data
это строка, у которой нет#read
метода. Каков второй параметр,a
?2. Если вы используете
send_data
для возврата файл, который вы хотите загрузить с помощью браузера, вы, вероятно, захотите добавитьdisposition: 'attachment; filename=exported_properties.csv'
или что-то подобное, согласно документам. Кроме того, вы должны выполнять своюsend_data
работу в контроллере, а не в своем классе. Верните данные CSV из класса и отправьте их пользователю в контроллере.3. @JohnP, он автоматически определяет расположение с этими значениями. Заголовок ответа содержит
Content-Disposition attachment; filename="exported_properties.csv"; filename*=UTF-8''exported_properties.csv
.send_data
находится у контроллера.4. Значит
export_to_csv
, метод находится в контроллере? Документы , вероятно, лучшее место для поиска информации о том, как это работает. Там даже есть пример кода для CSV-файла. В более общем плане, однако, если ответ доходит до браузера, но не отображается, это, вероятно, проблема с заголовками — рельсы не передают информацию, необходимую браузеру, чтобы знать, что делать с данными, поэтому вам нужно убедиться, что вы предоставляете ееsend_data
, правильно позвонив. Хотя, боюсь, я больше ничего не могу с собой поделать!
Ответ №1:
Добавление local: true
from_with
метода в представление решает проблему.
<%= form_with url: export_to_csv_admin_properties_url, local: true do |form| %>