Ruby on rails 正在干燥rails控制器代码以进行数据导出

Ruby on rails 正在干燥rails控制器代码以进行数据导出,ruby-on-rails,ruby,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(

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

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

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个这段代码的实例。是否有一种方法可以将此代码移动到另一个文件中,并向其中传递标签和字段的散列,以便只需维护导出代码的一个实例


谢谢

MVC的基本功能是拥有尽可能多的更轻薄的控制器,您的案例就是一个完美的例子,可以防止代码重复

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

将此方法移动到
模块
。 在
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
现在在您的
模型中包含
模块
,它将具有class
方法
新工作表

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

现在,您已经将逻辑移到了
模型中
下一步是重构此方法,使其更简单。

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

def self.export_subset_to_spreadsheet(users)
  ... your code ...
end
然后使用
User从控制器调用它。将\u子集\u导出到\u电子表格(@users)


这是第一步。您当然可以从那里进一步了解,但至少这可以让您摆脱最紧迫的问题:整个代码块的19个副本。

是的,问题是19个控制器中没有19个代码实例,我现在有19个模型中的19个代码实例-不确定这是否是一个巨大的进步?如何传入特定的标签和字段名称?向
方法添加更多属性
标签
名称
。。。然后相应地改变方法,这应该足以让我继续,谢谢!是的,问题是不是在19个控制器中有19个代码实例,我现在会在19个模型中有19个代码实例-不确定这是一个巨大的进步?我不确定为什么会有19个模型。。。19个实例中的不同项目是什么?(虽然我知道@Nermin的答案可能已经帮助了您;正如上面提到的,将标签和字段名列表作为额外参数添加到方法签名中非常简单,例如
def self.export\u to_subset\u to_电子表格(用户、标签、字段名)
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
def self.export_subset_to_spreadsheet(users)
  ... your code ...
end