[英]Rails 3 accessing has_many through join model in another controller
[英]Rails 3.2 Simplify Controller with Model Methods on has_many :through
我在瘦控制器上看到的大多數問題都涉及簡單的模型關系。 我的問題是,如果要更新具有多個參數及其關聯數組的多對多表單,如何通過將其全部移至模型方法來簡化任務? 例如,看下面的一個荒謬的大型控制器。 處理這個邪惡的混亂的最簡單方法是什么? 我不是在尋求語法上完美的答案,而是需要就此達成共識。
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
您可以采用以下幾種方法來實現所需的目標:
accepts_nested_attributes_for
。 使用嵌套屬性,您的控制器edit
方法將只需要與嵌套的@shipment
集合共享一個@shipment
實例變量。 update
操作僅調用update_attributes
。 當你正確使用嵌套的屬性,這應該是唯一一款叫你需要的,因為它會隱填充屬性為其shipment_products
。 shipment_products
模型中,使用after_save
回調,以紀念開出貨量。 但要注意,你的shipment_products模型不應該使用這個詞Product
(大寫)。 相反,它應該依靠其belongs_to
關系調用product.mark_open_shipment(difference)
。 difference
應重構為product_shipments的實例方法。 回調和update_attributes都將在一個事務中運行,這將確保原子性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.