Rails 4 ActiveRecord模型:正确使用_was来分隔两个数量

时间:2014-06-19 07:32:31

标签: ruby-on-rails activerecord

我正在构建一个电子商务应用,我有点卡住了。如果产品相同,我不想创建新的line_item。这是我的cart.rb模型

class Cart < ActiveRecord::Base
  has_many :line_items, dependent: :destroy
  has_many :products

  def add_product(product_id, size, color, quantity)
    current_item = line_items.find_by_product_id(product_id)
    if current_item
        current_item.quantity = 20
        current_item.quantity += current_item.quantity_was
    else
        current_item = line_items.build(product_id: product_id, size: size, color: color, quantity: quantity)
    end
    current_item
  end

  def total_price
    line_items.to_a.sum { |item| item.total_price }
  end

end

line_items控制器(在购物车中创建新行):

class LineItemsController < InheritedResources::Base
  def create
    @cart = current_cart
    product = Product.find(params[:product_id])
    size = params[:product][:size]
    color = params[:product][:color]
    quantity = params[:product][:quantity]
    @line_item = @cart.add_product(product.id, size, color, quantity)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to products_customer_cart_url,
          notice: 'You have added an item to your cart.' }
        #format.js { @current_item = @line_item }
        format.json { render json: @line_item,
          status: :created, location: @line_item }
      else
        format.html { render action: "new" }
        format.json { render json: @line_item.errors,
          status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @cart = current_cart

    @line_item = LineItem.find(params[:id])
    @line_item.destroy

    respond_to do |format|
      format.js {}
    end
  end

end

下面的产品show.html.erb(您选择项目的地方):

<%= form_for(@product, url: line_items_path(product_id: @product.id), html: {method: "update"}) do |f| %>
   <%= image_tag("https://s3.amazonaws.com/blah/mens_black_front.jpg" %>
     <table>
       <tr><td>Size:</td> <%= f.select(:size, @male_shirt_sizes.map { |value| value }, :include_blank => 'Select Size') %></td><tr>
       <tr><td>Color:</td> <%= f.select(:color, @shirt_colors.map { |value| value }, :include_blank => 'Select Color') %></td><tr>
       <tr><td>Quantity:</td> <%= f.select(:quantity, @quantity.map { |value| value }, :include_blank => 'Select Quantity') %></td><tr>
     </table>
    <%= f.submit "Add to Cart", :class => "btn btn-mega btn-primary", :id => "add-to-cart-btn" %>
<% end %>

- 但是,正如你所看到的那样,我现在只需将数字20放在那里进行测试。

- 我说我最初要添加一个项目,数量为4。

- line_item现在的数量为4。

- 当我去添加不同数量的相同产品(无论是1,2,3,4还是5)时,它会添加int 20(因为它应该,因为20在那里是硬编码的)。

但是,如何动态添加“新”数量,将初始数量添加到最新数量?

1 个答案:

答案 0 :(得分:1)

我已经回答了类似的问题here。将发布摘要

But how would I dynamically add the 'new' quantity, to add the initial quantity to the latest quantity?

问题是您的提交按钮将其带到商品的创建操作,从而在购物车内创建新商品

<强>修正:

您需要使用路径后请求(找到该项目)进行新操作,然后在该操作中更新其数量。

如果您查看按钮,或者我应该说创建新项目的表单,那么表单中的路径或网址会将其带到控制器内您的方法< / em>的。如果您更改其网址,则会将其转到您的自定义方法

为了实现这一目标,用户点击添加到购物车按钮 后,您需要js 动态更改网址或表单。类似的东西:

$(document).on("click","your_button_class",function(){
  $(this).closest("your_form_class").attr("action","path_of_new_method");
});

您还必须通过添加隐藏字段或其他内容,通过此表单提供您的项目ID,然后在控制器方法中找到该项目,并使用该ID更新其数量。

注意:您需要在提交表单后调用此js 并且已经创建了一个新项目,否则可能会给您带来麻烦。