【发布时间】:2014-04-30 17:07:26
【问题描述】:
我一直在 Rails 中创建购物车功能,我有以下模型:
购物车:
class Cart < ActiveRecord::Base
has_many :items
end
项目:
class Item < ActiveRecord::Base
belongs_to :cart
belongs_to :product
end
物品也有数量属性。
现在,我在购物车上有一个实例方法,给定商品将 a) 将商品保存到数据库并将其与购物车相关联,或者 b) 如果具有 product_id 的商品已经存在,只需更新数量即可。
代码如下:
def add_item(item)
if(item.valid?)
current_item = self.items.find_by(product_id: item.product.id)
if(current_item)
current_item.update(quantity: current_item.quantity += item.quantity.to_i)
else
self.items << item
end
self.save
end
end
这很好用。
但是,我想在控制台中对此进行测试,所以我在沙盒模式下打开了控制台并运行了以下命令:
cart = Cart.new #create a cart
cart.add_item(Item.new(product: Product.find(1), quantity: 5)) #Add 5 x Product 1
cart.items #lists items, I can see 5 x Product 1 at this point.
cart.add_item(Item.new(product: Product.find(1), quantity: 3)) #Add 3 x Product 1
cart.items #lists items, still shows 5 x Product 1, not 8x
cart.items.reload #reload collectionproxy
cart.items #lists items, now with 8x Product 1
在这里我创建了一个购物车,添加了 5 x 产品 1 的购买,我可以在 cart.items 中看到它。如果再添加 3 x 产品 1 的购买,cart.items 仍将购买列为 5 x 产品 1,直到我手动重新加载集合代理。
我可以添加更多产品,这些会显示出来,只是在更新现有产品时,它不会更新集合。
我也对这个方法进行了测试,通过了。
before(:each) do
@cart = create(:cart)
@product = create(:product)
@item = build(:item, product: @product, quantity: 2)
end
context "when the product already exists in the cart" do
before(:each) {@cart.add_item(@item)}
it "does not add another item to the database" do
expect{@cart.add_item(@item)}.not_to change{Item.count}
end
it "does not add another item to the cart" do
expect{@cart.add_item(@item)}.not_to change{@cart.items.count}
end
it "updates the quantity of the existing item" do
@cart.add_item(@item)
expect(@cart.items.first.quantity).to eq 4
end
end
context "when a valid item is given" do
it "adds the item to the database" do
expect{@cart.add_item(@item)}.to change{CartItem.count}.by(1)
end
it "adds the item to the cart" do
expect{@cart.add_item(@item)}.to change{@cart.items.size}.by(1)
end
end
我想知道的是,为什么我在控制台中使用这个方法时,必须重新加载CollectionProxy?
【问题讨论】:
标签: ruby-on-rails ruby rspec rspec-rails rails-console