我今天開始閱讀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創建代碼放在控制器動作中?必須有更優雅/可重用的方式。 –