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