干燥轨道控制器代码以进行数据导出

时间:2015-01-28 13:56:50

标签: ruby-on-rails ruby

不确定这是否是一个合适的问题,请原谅我。

我在控制器操作中有以下代码

unless @users.empty?
  book = Spreadsheet::Workbook.new
  sheet1 = book.create_worksheet :name => 'export'
  sheet1.row(0).concat ["Label1", "Label2", "Label3"]
  @users.each_with_index do |e, i|
    sheet1.row(i+1).concat([e.field1, e.field2, e.field3])
  end
  require 'stringio'
  data = StringIO.new ''
  book.write data
  send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => "export_#{l(Date.today)}.xls"
end

这允许我在运行导出的表单上有一个按钮。虽然这非常有用,但我在整个地方使用此代码。实际上,我在应用程序中的各种控制器中有19个此代码实例。有没有办法可以将此代码移动到另一个文件,并将标签和字段的哈希值传递给它,这样我只需要维护一个导出代码实例?

感谢

2 个答案:

答案 0 :(得分:0)

MVC的基础是尽可能多的皮肤控制器,你的情况就是完美的例子,以防止重复你的代码。

解决方案是将代码移至models M模式中的MVC,它负责所有业务逻辑。

将此方法移至module。 在app/models/concers/文件夹中创建新文件sheetable.rb

require 'active_support/concern'

module Sheetable
  extend ActiveSupport::Concern

  module ClassMethods    
    def new_sheet objects
      unless objects.empty?
        book = Spreadsheet::Workbook.new
        sheet1 = book.create_worksheet :name => 'export'
        sheet1.row(0).concat ["Label1", "Label2", "Label3"]
        objects.each_with_index do |e, i|
          sheet1.row(i+1).concat([e.field1, e.field2, e.field3])
        end
        require 'stringio'
        data = StringIO.new ''
        book.write data    
      end
    end
  end
end

现在在module中添加model,它将会有method new_sheet个分组。

class User < ActiveRecord::Base
  ...
  include Sheetable
  ...
end

或其他模型

class OtherModel < ActiveRecord::Base
  ...
  include Sheetable
  ...
end

使用此

data = User.new_sheet(@users) # or OtherModel.new_sheet(@other_models)
if data
 send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => "export_#{l(Date.today)}.xls"
end

现在您已将逻辑移至model下一步是重构此方法,使其更简单。

答案 1 :(得分:0)

我首先将代码移到责任所在的位置。您似乎正在将某组用户的数据导出到电子表格中。所以我将代码移到User类,例如

def self.export_subset_to_spreadsheet(users)
  ... your code ...
end

然后使用User.export_subset_to_spreadsheet(@users)从控制器中调用它。

这是第一步。你当然可以从那里进一步发展,但至少这可以让你摆脱最紧迫的问题:整个代码块的19个重复。