尝试检索存储在会话中的对象时出错

时间:2015-07-29 14:36:03

标签: ruby-on-rails ruby ruby-on-rails-4

我收到以下错误:

 NoMethodError in StoreController#add_to_cart
 undefined method `product_id' for #<Hash:0xb9d34aa0>

 Extracted source (around line #11):

 9      @cart_items = find_cart_items
 10      @cart_total_price = session[:cart_total_price]
 11     item = @cart_items.find {|i| i.product_id == product}
 12      if item
 13        item.update_quantity_by_one
 14      else

store_controller.rb

class StoreController < ApplicationController

  def index
      @products = Product.salable_items
  end

  def add_to_cart
      product = Product.find(params[:id])
        @cart_items = find_cart_items
      @cart_total_price = session[:cart_total_price]
        item = @cart_items.find {|i| i.product_id == product}
      if item
        item.update_quantity_by_one
      else
        li = LineItem.new
        if li.save
          li.for_product(product)
          @cart_items << li
        else
          flash[:alert] = "Error encountered."
        end
      end

      #@cart_items << LineItem.for_product(product)
      @cart_total_price += product.price
        redirect_to display_cart_path
  end

  def display_cart
      @items = session[:cart_items]
  end

  private 
    def find_cart_items
        if session[:cart_items].nil?
        session[:cart_total_price] = 0
        session[:cart_items] = Array.new
      else
        session[:cart_items]
      end
    end
end

line_item.rb

class LineItem < ActiveRecord::Base
    belongs_to :product

    def for_product(product) 
        update_attribute(:quantity, 1)
        update_attribute(:product, product)
        update_attribute(:unit_price, product.price)
    end

    def update_quantity_by_one
        self.quantity += 1
    end
end

我将第二项添加到购物车时出现此错误,即LineItem中已存在一个session[:cart_items]时。我已经在rails控制台中模拟了这一系列事件,其中一切正常,我能够在执行@cart_items.find {|i| i.product_id == product}时检索正确的对象,但是当我在浏览器中启动时,会出现上述错误。问题可能是什么?为什么要检索“哈希”?

2 个答案:

答案 0 :(得分:1)

item = @cart_items.find {|i| i.product_id == product}

似乎i是哈希,因此您无法在其上调用#product_id

尝试i['product_id']i[:product_id]。如果这不起作用,请尝试使用pry或类似工具进行调试,并找出i的内容。

此外,这似乎没有意义:

item = @cart_items.find {|i| i.product_id == product}

你的意思是:

item = @cart_items.find {|i| i.product_id == product.id}

答案 1 :(得分:1)

您似乎正在尝试在会话中保存一组ActiveRecord对象。

会话数据已序列化,有时会出现意外结果。有很多关于这可能是一个问题的参考,例如, Railscasts: Dangers of Model in Session

要查看正在进行的操作,您可以停止&amp;调试(或只是放置)@cart_items变量,紧接在控制器的第9行之后。我打赌@cart_items变量不包含您的想法。 (似乎会话将其反序列化为哈希数组。)

标准建议是在会话中保存LineItem id的数组,而不是LineItem对象本身的数组。然后会话序列化/反序列化应该非常简单,没有任何意外。