我有几个部分的解决方案,但我很难将它们组合在一起。
我有一个包含两个文本字段的页面(在form_tag中),其中我将输入一个日期时间字符串,其中包含我要以CSV格式下载的记录的开始日期和结束日期。
我可以使用submit_tag并获取两个日期,但后来我不知道如何让视图告诉控制器我想要一个CSV,所以。我可以使用link_to,但是params会被遗忘。
视图和控制器看起来有点不稳定,因为我试图找出这些东西应该如何协同工作。例如,我不会发送链接和按钮。为了简洁/隐私,我还根据需要删除/更改了内容。
show.html.erb:
<%= form_tag do %>
<br/><br/>
<%= label_tag :start_date, "From:" %>
<%= text_field_tag :start_date, nil, size: 40 %>
<%= label_tag :end_date, "To:" %>
<%= text_field_tag :end_date, nil, size: 40 %>
<br/>
<%= link_to "Export Report", report_path(:csv) %>
<%= submit_tag("Generate .CSV", format: :csv) %><br/><br/>
<% end %>
report_controller.rb:
require 'csv'
class ReportController < ApplicationController
def show
if params[:start_date]
@data = get_data(params[:start_date], params[:end_date])
respond_to do |format|
format.html
format.csv
end
end
end
def build_csv_enumerator(header, data)
Enumerator.new do |y|
CSVBuilder.new(header, data, y)
end
end
def download
if params[:start_date]
@data = get_data(params[:start_date], params[:end_date])
respond_to do |format|
format.html
format.csv
end
end
redirect_to action: "show"
end
private def csv_filename
"report-#{Time.now.to_s}.csv"
end
end
class CSVBuilder
attr_accessor :output, :header, :data
def initialize(header, data, output = "")
@output = output
@header = header
@data = data
end
def build
output << CSV.generate_line(header)
data.each do |row|
output << CSV.generate_line(row)
end
output
end
end
download.csv.erb:
<%- headers = ["name", "email", "created_at"] -%>
<%= CSV.generate_line(headers) %>
<%- @data.each do |line| -%>
<%- row = line.values_at(*headers) -%>
<%= CSV.generate_line(row) %>
<%- end -%>
答案 0 :(得分:3)
由于您要下载CSV,请求应为GET
请求。
您的链接应该如<a href="/reports/1.csv?from=2017-01-01&to=2017-12-31">Download</a>
。我建议你在浏览器上构建这个URL(这意味着使用javascript,而不是rails)。
您的rails应用程序必须了解扩展程序.csv
。这可以在config/initializers/mime_types.rb
Mime::Type.register "text/csv", :csv
现在您可以将CSV发送到浏览器
class ReportsController < ApplicationController
def show
@csv = ...
respond_to do |format|
# ...
format.csv do
send_data @csv.to_s # what you send must be a string
end
end
end
end
答案 1 :(得分:1)
链接是独立的;提交按钮(通常)将表单(包含所有非disabled
,name
- 有值)提交到表单的操作网址(除非您通过JavaScript提交,在这种情况下你可以做任何你想做的事,显然。)
因此,您没有在submit_tag
上指定网址,而是在form_tag
上指定:
启动一个表单标记,将该操作指向配置了
url_for_options
的网址,就像ActionController::Base#url_for
一样。
答案 2 :(得分:0)
作为提到的答案之一,您需要在format
上指定form_tag
。由于需要在format
中设置url_options
,而不是在其他form_tag
选项中设置,因此可能会很棘手。例如:
<%= form_tag({controller: 'my_controller', method: 'my_method', format: 'csv'}, method: "get") do %>
...fields
<%= submit_tag 'Submit' %>
<% end %>