2015-11-01 64 views
0

我有2種型號 - Order和Item:更新父對象時,子對象滿足一定條件

order.rb:

class Order < ActiveRecord::Base 
    has_many :items 
end 

item.rb的:

class Item < ActiveRecord::Base 
belongs_to :order 
end 

架構項目:

t.decimal "price",  precision: 12, scale: 3 
t.string "status" 

schema for訂單:

t.string "status" 

當用戶收到物品時,物品的狀態將標記爲已發貨。那麼,如何將訂單狀態更新爲「完成」,條件是所有項目的狀態都更新爲「已發貨」?

回答

0

你需要更新你的items表包括foreign key,它與orders

$ rails g new migration AddOrderIDToItems 

#db/migrate/add_order_id_to_items______.rb 
class AddOrderIdToItems < ActiveRecord::Migration 
    def change 
     add_column :items, :order_id, :integer 
    end 
end 

$ rake db:migrate 

你可以閱讀更多關於爲什麼這是重要的here

enter image description here

-

這將允許你做fol降脂:

#app/models/order.rb 
class Order < ActiveRecord::Base 
    has_many :items, inverse_of: :order 
end 

#app/models/item.rb 
class Item < ActiveRecord::Base 
    belongs_to :order, inverse_of: :items 
    after_save :check_order, on: :update 

    private 

    def check_order 
     items = Item.where(order_id: order.id).where.not(status: "shipped").count 
     order.update(status: "complete") if items > 0 
    end 
end 

這將允許您使用以下:

@item = Item.find params[:id] 
@item.update(status: "shipped") #-> "check_order" will happen, saving "order" as "complete" if all items are shipped 

這樣做的真正的解決方法是創建一個has_many :through關係,許多Items很多Orders關聯。通過這種方式,可以爲「已裝船」標記每個OrderItems的:

#app/models/order.rb 
class Order < ActiveRecord::Base 
    has_many :order_items 
    has_many :items, through: :order_items 
end 

#app/models/order_item.rb 
class OrderItem < ActiveRecord::Base 
    #columns id | order_id | item_id | created_at | updated_at 
    belongs_to :order 
    belongs_to :item 

    after_save :check_order, on: :update 

    private 

    def check_order 
     items = Item.where(order_id: order.id).where.not(status: "shipped").count 
     order.update(status: "complete") if items > 0 
    end 
end 

#app/models/item.rb 
class Item < ActiveRecord::Base 
    has_many :order_items 
    has_many :orders, through: :order_items 
end 

你只需要引入OrderItem模型(修改ItemOrder模型是沒有必要的):

enter image description here

這將允許你做到以下幾點:

@order = Order.find params[:id] 
@item = Item.find params[:id] 

@order.items << @item #-> adds "item" to order 

你會是一個可以使用以下命令設置訂單是否已「完成」:

@order = Order.find params[:id] 

@item = @order.order_items.find x 
@item.update status: "shipped" 
0

我會去這樣的事情:

class Item < ActiveRecord::Base 
    def complete_order 
    order.complete if all_items_shipped? 
    end 

    def shipped? 
    status == 'shipped' 
    end 

    private 

    def all_items_shipped? 
    order.items.all?(&:shipped?) 
    end 
end 

class Order < ActiveRecord::Base 
    def complete 
    update status: 'complete' 
    end 
end 

然後調用item.complete_order每次一Item被標記爲shipped

+0

我應該在哪裏調用'item.complete_order'還是應該使用像after_update之類的回調?如果我得到了另一個條件,即該項目的狀態=「退款」,所以如果兩個項目是「發貨」,一個項目是「退款」,則訂單狀態應標記爲「不完整」。謝謝。 – pyfl88

+0

你說過:*當用戶收到商品*時,商品的狀態將被標記爲已發貨,因此您可以在更新商品狀態的同一時刻/地點調用item.complete_order。對於第二個問題,我會將它添加到問題的正文中,因爲它實際上是另一個功能。您可以用類似的方式複製邏輯來處理這種情況。 – dgilperez

相關問題