我今天开始阅读Rails Antipatterns,并希望将其中一些实践付诸实践。我正在重构最初内置在控制器中的CSV导出。由于这是一个不好的做法,我把它分解成模型......然后是它自己的模型。这样我可以将该方法用于其他目的。在Rails 3模型中调用实例方法
我有下面的方法模型:
#app/models/imagery_request.rb
class ImageryRequest < ActiveRecord::Base
def convert
ImageryRequestConverter.new(self)
end
end
我有另一种模式是这样的:
#app/models/imagery_request_converter.rb
class ImageryRequestConverter
attr_reader :imagery_requests
def initialize(imagery_requests)
@imagery_requests = imagery_requests
end
def to_csv
csv_string = FasterCSV.generate do |csv|
# header row
csv << ["id", "service_name", "description", "first_name", "last_name", "email", "phone_contact", "region",
"imagery_type", "file_type", "pixel_type", "total_images",
"tile_size", "progress", "expected_date", "high_priority", "priority_justification",
"raw_data_location", "service_overviews", "is_def",
"isc_def", "special_instructions", "navigational_path", "FY Queue",
"created_at", "updated_at"]
# data rows
@imagery_requests.each do |ir|
csv << [ir.id, ir.service_name, ir.description, ir.first_name, ir.last_name, ir.email,
ir.phone_contact, ir.region, ir.imagery_type, ir.file_type, ir.pixel_type,
ir.total_images, ir.tile_size, ir.progress, ir.expected_date, ir.high_priority,
ir.priority_justification, ir.raw_data_location, ir.service_overviews,
ir.is_def, ir.isc_def, ir.special_instructions, ir.navigational_path,
ir.fyqueue, ir.created_at, ir.updated_at
]
end
# send it to the browser with proper headers
send_data csv_string,
:type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment; filename=Imagery_Requests-#{Time.now.strftime("%Y%m%d")}.csv"
end
end
end
当我尝试在我看来与参考这个:
<%= link_to @imagery_requests.convert.to_csv %>
我收到一个错误:
undefined method `convert' for #<ActiveRecord::Relation:0x21f966d0>
如何调用此方法?
所以我基本上必须把所有CSV创建代码放在控制器动作中?必须有更优雅/可重用的方式。 –