Add multiple items to a cart at the same time

2019-07-19 07:19发布

问题:

I have the following relations :

Class CartItem
belongs_to :cart
belongs_to :product

Class Product (<=> category)
has_many :cart_items


Class Cart
has_many :cart_items

When someone adds a product to his cart, it creates a line in the CartItem table with cart.id and product.id. I can add et remove a product to a cart on the edit page, it works.

But now I would like to add or remove more than one product to a cart at the same time. I just need an input number field when the customer could put the number we want to add/remove. However, I don't manage to do it because in the edit form, if i put a field called for example "number" (for each product) an error will obviously appear because there is no attribute "number". I should probably add a "field_tag" but how can it work ? Thanks in advance

回答1:

I work on an eCommerce gem written with Rails called Spree. Here's how we've solved that problem.

We have 4 models: Variant, Product, Order and LineItem. These form the basics of our ordering system. A variant can be considered like a "mutation" of a product. Say you have a TShirt that could come in Red, Green or Blue. The Product is the TShirt, while the colours are the variants.

Variants are linked to Orders by way of LineItems. The LineItem object stores: a variant_id, a quantity and the current price of the variant, just in case that changes later. You don't want prices changing on users unexpectedly!

The logic for adding an item to the cart is simply a form with a variant_id and a quantity field on the product's page. Here's Spree's version. The controller's action that deals with that form basically takes the variant_id and quantity, and does this:

  1. Checks if an order already exists
  2. If an order doesn't exist, creates one
  3. Creates a new line item on the order with the quantity and variant_id specified, and stores the price.

Spree's voodoo around this is a little more complex as we care about inventory levels and so on, but that's the basic gist of it.

When the user goes to view their cart, we present them with a form with all the line items and a quantity numeric field. That form looks like this:

checkout http://f.cl.ly/items/3P3t3o1F283a1e0Z3e0C/Screen%20Shot%202013-07-11%20at%208.39.20%20AM.png

The code to produce that form is in three files: orders/edit.html.erb, orders/_form.html.erb and orders/_line_item.html.erb

That form works by submitting to OrdersController#update, and due to the fields in the form being nested attributes, the entire order and its line items are updated suitably.

I hope this helps you!