Динамические средства поиска возвращают новый объект, отличный от любого объекта в коллекции has_many?

Я пытаюсь найти объект из коллекции has_many с помощью динамических поисковых систем, а затем обновить атрибут возвращаемого объекта. Но я действительно не знаю, когда обновленное значение атрибута будет синхронизировано с коллекцией has_many. Поскольку я обнаружил, что возвращенный объект — это новый объект, отличный от любого из объектов в коллекции has_many.

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

После обновления количества current_item при рендеринге корзины количество line_item в корзине по-прежнему будет значением до обновления. Но, тем не менее, в следующий раз при вызове LineItemsController.create количество line_item в корзине обновилось. Итак, есть ли какая-либо информация о том, когда количество line_item в корзине было обновлено?


person Joey Zhang    schedule 20.03.2012    source источник


Ответы (1)


Самым простым решением может быть вызов cart.line_items(true) после того, как вы обновите отдельную позицию. Это вынуждает Rails перезагрузить всю ассоциацию из базы данных, которая должна включать изменения в количестве вашей позиции.

Вы также можете использовать detect вместо find_by_product_id, чтобы получить элемент строки непосредственно из массива элементов строки. Это гарантирует, что вы используете один и тот же объект, но для этого требуется сначала загрузить все позиции из базы данных (что, похоже, вы уже делаете):

current_item = line_items.detect { |item| item.product_id == product_id }
person Brandan    schedule 20.03.2012
comment
Рад помочь. Пожалуйста, не забудьте принять ответ (и, при желании, проголосовать за него), если он решит вашу проблему. - person Brandan; 21.03.2012