문제

I'm trying to find a object from the has_many collection by dynamic-finders, and then update the attribute of the returned object. But I really don't know when the updated attribute value will be synchronized to the has_many collection. Because I found the returned object is a new object different from any of the objects in the has_many collection.

class Cart < ActiveRecord::Base
  has_many :line_items, :dependent => destroy

  def add_product(product_id)
    current_item = line_items.find_by_product_id(product_id) 
    #here current_item is #<LineItem:0x007fb1992259c8>
    #but the line_item in has_many collection line_items is #<LineItem:0x007fb19921ed58>
    if current_item
      current_item.quantity += 1
    else
      current_item = line_items.build(:product_id => product_id)
    end
    current_item
  end
...
end

class LineItemsController < ApplicationController
  ...
  def create
    @cart = current_cart
    product = Product.find(params[:product_id])
    @line_item = @cart.add_product(product_id)

    respond_to do |format|
      if @line_item.save
        format.js { @current_item = @line_item }
      end
    end
  end
  ...
end

After updating the quantity of current_item, when render the Cart, the quantity of the line_item in the cart still be the value before updaing. But however, the next time when calling LineItemsController.create, the quantity of the line_item in the cart has been updated. So is there any idea about when the quantity of the line_item in the cart been updated?

도움이 되었습니까?

해결책

The simplest solution may be to call cart.line_items(true) after you've updated the individual line item. This forces Rails to reload the entire association from the database, which should include the changes to your line item quantity.

You could also use detect instead of find_by_product_id to fetch the line item directly from the array of line items. This would guarantee that you're using the same object, but it requires loading all the line items from the database first (which it sounds likes you may already be doing):

current_item = line_items.detect { |item| item.product_id == product_id }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top