コントローラーのスキニーアップに関して私が見たほとんどの質問は、単純なモデルの関係を扱っています。私の質問は、複数のパラメーターとそれに関連付けられた配列を使用して多対多のフォームを更新する場合、すべてをモデル メソッドに移動してタスクを簡素化するにはどうすればよいですか? たとえば、以下のとてつもなく大きなコントローラーを見てください。この不浄な混乱に対処する最も簡単な方法は何ですか? 私は構文的に完璧な答えを探しているわけではありませんが、これを進める方向性について一般的なコンセンサスが必要です。
def update
@shipment = Shipment.joins(:products).find(params[:id], :readonly => false)
@shipment.update_attributes(params[:shipment])
@shipment_products = params[:product_shipments]
@product_shipment_array= array_from_hash(@shipment_products)
@shipment.product_shipments.each do |product_shipment|
product_shipment.update_attributes(:qty_shipped => params[:product_shipments][product_shipment.id.to_s][:qty_shipped], :pickup_item => params[:product_shipments][product_shipment.id.to_s][:pickup_item])
end
@product_shipment_array.each do |p|
if p['old_pickup_item'] == "true" and p['pickup_item'].to_i==0
@difference = (p['qty_shipped'].to_i)
Product.mark_open_shipment(@difference, p['product_id'])
elsif p['old_pickup_item'] == "false" and p['pickup_item'].to_i==1
@difference = -(p['old_qty_shipped'].to_i)
Product.mark_open_shipment(@difference, p['product_id'])
else
@difference = -(p['old_qty_shipped'].to_i - p['qty_shipped'].to_i)
Product.mark_open_shipment(@difference, p['product_id'])
end
end
respond_with @shipment, :location => shipments_url
end
私のモデルでは、このようなモデルメソッドを宣言したい
Class Shipment < ActiveRecord::Base
.
.
.
def update_shipment_attributes
#all business logic
end
end
コントローラーを次のようなものにすることを期待して:
def update
@shipment = Shipment.joins(:products).find(params[:id], :readonly => false)
@shipment.update_attributes(params[:shipment])
@shipment_products = params[:product_shipments]
Shipment.update_shipment_attributes
respond_with @shipment, :location => shipments_url
end