从activeadmin批处理操作下载zip文件

时间:2018-08-31 18:01:02

标签: ruby-on-rails download activeadmin

我想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(...),但是出于代码方面的考虑,不建议这样做。

1 个答案:

答案 0 :(得分:1)

已解决。我将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
...