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