Ruby on Rails - 通过活动记录has_many关联减少列

时间:2012-01-31 04:04:14

标签: ruby-on-rails-3 activerecord has-many

我正在构建一个带有库存控制和购物车的电子商务应用程序。付款获得批准后,我想减少购物车中每件商品的数量。这意味着,我需要减少属于carts的line_items的产品数量列。

我可以通过这样的活动记录界面(在我的购物车模型中)减少一个:

self.line_items[0].product.decrement(:qty)

并直接执行查询:

connection.execute("UPDATE products SET qty = qty - 1 WHERE id IN (SELECT product_id FROM line_items WHERE cart_id = #{self.cart_id})")

但这两种方法似乎都不正确。后者直接查询db模式,这显然不是最佳实践。第一种方法更好,但我不知道如何在所有记录上实现它。

我的模特是这样的:

class Product < ActiveRecord::Base
end

class Cart < ActiveRecord::Base  
  has_many :line_items
end

class LineItem < ActiveRecord::Base
  belongs_to :cart
  belongs_to :product
end

架构是:

create_table "carts", :force => true do |t|
  ..
end

create_table "line_items", :force => true do |t|
  ..
  t.integer  "product_id"
  t.integer  "cart_id"
end

create_table "products", :force => true do |t|
  ..
  t.integer  "qty"
end

我确信有一种优雅的方式可以做到这一点。有人可以帮帮我吗?

非常感谢,
轮辋

1 个答案:

答案 0 :(得分:3)

update_counters怎么样? http://apidock.com/rails/ActiveRecord/CounterCache/update_counters

class Cart < ActiveRecord::Base  
  has_many :line_items
  has_many :products, :through => :line_items
end

Product.update_counters(cart.products, :qty => -1)
# => UPDATE "products" SET "qty" = COALESCE("qty", 0) - 1 WHERE "products"."id" IN (1, 2)