簡體   English   中英

在has_many:through上使用模型方法簡化Rails 3.2控制器

[英]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

您可以采用以下幾種方法來實現所需的目標:

  1. 研究使用嵌套表單accepts_nested_attributes_for 使用嵌套屬性,您的控制器edit方法將只需要與嵌套的@shipment集合共享一個@shipment實例變量。
  2. 考慮讓您的update操作僅調用update_attributes 當你正確使用嵌套的屬性,這應該是唯一一款叫你需要的,因為它會隱填充屬性為其shipment_products
  3. 在你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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM