从 activeadmin 批处理操作下载 zip 文件
Download zip file from activeadmin batch action
我想 send_data
给在我们网站上使用 activeadmin 界面的管理员。此数据是一个 zip 文件,如果满足所选项目的某些条件,则可以下载。
我创建了一个服务来处理其背后的逻辑(相当复杂)。所以我可以从 activeadmin 调用:
batch_action :action_name, form: {selection: ['...']} do |ids, inputs|
response = MyService.new(ids, inputs[:selection]).my_method
redirect_to collection_path
end
为我服务MyService.rb
:
...
def my_method
...
if condition
zip_data = Zip::OutputStream.write_buffer do |zip|
zip.put_next_entry("#{original_file_name}.xml")
zip << File.read(original_file)
end
send_data(zip_data.read, :type => 'application/zip', :filename => "#{original_file_name}.zip")
# here send_data throws an error because it's a controller method
else
...
end
...
end
...
但是如何正确使用send_data
方法呢?也许我必须重组一些东西?我知道您可能可以在控制器外部执行 ActionController::DataStreaming.send_data(...)
,但是为了代码的缘故,不建议这样做。
已解决。我将 send_data
放在 batch_action
代码中,如下所示:
batch_action :action_name, form: {selection: ['...']} do |ids, inputs|
response = MyService.new(ids, inputs[:selection]).my_method
redirect_to collection_path
send_data(response[:zip][:data].read, :type => 'application/zip', :filename => "#{response[:zip][:name]}.zip") if response[:zip].present?
end
其中响应包含要发送的 zip 数据(在发送之前需要用 zip_data.rewind
倒带)。 my_service.rb
现在是:
...
def my_method
...
if condition
zip_data = Zip::OutputStream.write_buffer do |zip|
zip.put_next_entry("#{original_file_name}.xml")
zip << File.read(original_file)
end
zip_data.rewind
response[:zip] = {data: zip_data, name: original_file_name}
else
...
end
...
end
...
我想 send_data
给在我们网站上使用 activeadmin 界面的管理员。此数据是一个 zip 文件,如果满足所选项目的某些条件,则可以下载。
我创建了一个服务来处理其背后的逻辑(相当复杂)。所以我可以从 activeadmin 调用:
batch_action :action_name, form: {selection: ['...']} do |ids, inputs|
response = MyService.new(ids, inputs[:selection]).my_method
redirect_to collection_path
end
为我服务MyService.rb
:
...
def my_method
...
if condition
zip_data = Zip::OutputStream.write_buffer do |zip|
zip.put_next_entry("#{original_file_name}.xml")
zip << File.read(original_file)
end
send_data(zip_data.read, :type => 'application/zip', :filename => "#{original_file_name}.zip")
# here send_data throws an error because it's a controller method
else
...
end
...
end
...
但是如何正确使用send_data
方法呢?也许我必须重组一些东西?我知道您可能可以在控制器外部执行 ActionController::DataStreaming.send_data(...)
,但是为了代码的缘故,不建议这样做。
已解决。我将 send_data
放在 batch_action
代码中,如下所示:
batch_action :action_name, form: {selection: ['...']} do |ids, inputs|
response = MyService.new(ids, inputs[:selection]).my_method
redirect_to collection_path
send_data(response[:zip][:data].read, :type => 'application/zip', :filename => "#{response[:zip][:name]}.zip") if response[:zip].present?
end
其中响应包含要发送的 zip 数据(在发送之前需要用 zip_data.rewind
倒带)。 my_service.rb
现在是:
...
def my_method
...
if condition
zip_data = Zip::OutputStream.write_buffer do |zip|
zip.put_next_entry("#{original_file_name}.xml")
zip << File.read(original_file)
end
zip_data.rewind
response[:zip] = {data: zip_data, name: original_file_name}
else
...
end
...
end
...