ruby on rails - Update parent object when child objects meet certain condition -
i have 2 models - order , item:
order.rb:
class order < activerecord::base has_many :items end item.rb:
class item < activerecord::base belongs_to :order end schema item:
t.decimal "price", precision: 12, scale: 3 t.string "status" schema order:
t.string "status" item's status marked shipped when user received items. how can update order status "complete", in condition items' status updated "shipped"?
you need update items table include foreign key, relating 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 you can read more why important here:
-
this allow following:
#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 this allow use following:
@item = item.find params[:id] @item.update(status: "shipped") #-> "check_order" happen, saving "order" "complete" if items shipped the real fix create has_many :through relationship, associate many items many orders. way, can mark each of orderitems "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 you need introduce orderitem model (changes item , order models not necessary):
this allow following:
@order = order.find params[:id] @item = item.find params[:id] @order.items << @item #-> adds "item" order you'll able use following set whether order has been "completed" or not:
@order = order.find params[:id] @item = @order.order_items.find x @item.update status: "shipped" 

Comments
Post a Comment