Ruby on rails 当子对象满足特定条件时更新父对象
我有两种型号-订单和项目: order.rb:Ruby on rails 当子对象满足特定条件时更新父对象,ruby-on-rails,Ruby On Rails,我有两种型号-订单和项目: order.rb: class Order < ActiveRecord::Base has_many :items end 订单模式: t.string "status" 当用户收到项目时,项目的状态将标记为已发货。那么,在所有项目的状态都更新为“已发货”的情况下,如何将订单状态更新为“已完成” 我喜欢这样的东西: class Item < ActiveRecord::Base def complete_order order
class Order < ActiveRecord::Base
has_many :items
end
订单模式:
t.string "status"
当用户收到项目时,项目的状态将标记为已发货。那么,在所有项目的状态都更新为“已发货”的情况下,如何将订单状态更新为“已完成” 我喜欢这样的东西:
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
class项
然后调用
项目。每次项目
标记为已发货
时,完成订单
。您需要更新项目
表以包含一个,将其与订单
关联:
$ 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
真正的解决方法是创建一个
has\u many:通过关系,将许多项目关联到许多订单。通过这种方式,您可以将每个OrderItems
标记为“已发货”:
然后,您可以使用以下设置订单是否已“完成”:
我应该在哪里调用项目。完成订单
还是像更新后那样使用回调?如果我得到了另一个条件,项目的状态=“退款”,那么如果2个项目是“已发货”,1个项目是“退款”,订单的状态应该标记为“未完成”。谢谢。您说过:当用户收到商品时,商品的状态将标记为已发货,因此您可以调用Item。在更新商品状态的同一时刻/地点完成订单。对于第二个问题,我将把它添加到问题的主体中,因为它实际上是另一个特性。您可以用类似的方式复制逻辑来处理该情况。
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
$ 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
#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
#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
@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"