1

我有 2 个模型:

Store has_many :dishes

Dish belong_to :store

我使用 session 来存储我的购物车:

session[:cart] ||= Cart.new

class Cart
  attr_reader :items, :key_items
  def initialize
    @items = Hash.new
    @key_items = Hash.new
  end

  def add_dish(dish)
    #binding.pry
    if @key_items[dish.store_id].nil?
      @items[dish.store_id] = Array.new
      @key_items[dish.store_id] = dish.store
    end

    current_item = @items[dish.store_id].find{|item| item.dish == dish}

    if current_item
       current_item.increment_quantity
    else
      @items[dish.store_id] << CartItem.new(dish)
    end
  end
end

如果@key_items[dish.store_id] = dish.store, session[:cart] 转储将崩溃,如下所示:

{"cart"=>
  #<Cart:0x007fa8742deeb0
   @items=
    {1=>
      [#<CartItem:0x007fa8742dedc0
        @dish=
         #<Dish id: 1, store_id: 1, name: "meat", count: 30, remaining_count: 30, price_cents: 1100, price_cents_currency: "CNY", image: nil, description: nil, created_at: "2012-10-11 07:38:26", updated_at: "2012-10-11 07:38:26">,
        @new_record=false>]},
   @quantity=1>,
 :@key_items=>
  {1=>
    #<Store id: 1, name: "ITChef", created_at: "2012-10-11 07:38:26", updated_at: "2012-10-11 07:38:26", start_price_cents: 2500, start_price_cents_currency: "CNY", fare_cents: 800, fare_cents_currency: "CNY">}}

如果@key_items[dish.store_id] = Store.find_by_id(dish.store_id),则转储如下所示:

{"cart"=>
  #<Cart:0x007f9ffc2dc780
   @items=
    {1=>
      [#<CartItem:0x007f9ffc2dc6b8
        @dish=
         #<Dish id: 1, store_id: 1, name: "meat", count: 30, remaining_count: 30, price_cents: 1100, price_cents_currency: "CNY", image: nil, description: nil, created_at: "2012-10-11 07:38:26", updated_at: "2012-10-11 07:38:26">,
        @quantity=1>]},
   @key_items=
    {1=>
      #<Store id: 1, name: "IT厨房", created_at: "2012-10-11 07:38:26", updated_at: "2012-10-11 07:38:26", start_price_cents: 2500, start_price_cents_currency: "CNY", fare_cents: 800, fare_cents_currency: "CNY">}>,
 :@stale_state=>nil}

为什么?

我一直在跟踪

   39: def set_session(env, session_id, new_session, options)
    40:   with_lock(env, false) do
    41:     @pool.set session_id, new_session, options
 => 42:     session_id
    43:   end
    44: end


[1] pry(#<ActionDispatch::Session::RedisStore>)> new_session
=> {"cart"=>
  #<Cart:0x007fce3f09f3c0
   @items=
    {1=>
      [#<CartItem:0x007fce3f0e1338
        @dish=
         #<Dish id: 2, store_id: 1, name: "糖醋里脊", count: 30, remaining_count: 30, price_cents: 2250, image: nil, description: nil, created_at: "2012-10-17 06:36:59", updated_at: "2012-10-17 06:36:59">,
        @quantity=1>]},
   @key_items=
    {1=>
      #<Store id: 1, name: "it厨房", start_price_cents: 3400, fare_price_cents: 1000, average_time: nil, announcement: nil, image: "it.jpg", is_active: true, created_at: "2012-10-17 06:36:59", updated_at: "2012-10-17 06:36:59">}>,
 "_csrf_token"=>"ZEx7qGOrjq7jra/NtXkm96YCj2DrY1CHkzUHqhvqTns="}

[2] pry(#<ActionDispatch::Session::RedisStore>)> @pool.get session_id
=> {"cart"=>
  #<Cart:0x007fce3f9e92c8
   @items=
    {1=>
      [#<CartItem:0x007fce3f9e94d0
        @dish=
         #<Dish id: 2, store_id: 1, name: "糖醋里脊", count: 30, remaining_count: 30, price_cents: 2250, image: nil, description: nil, created_at: "2012-10-17 06:36:59", updated_at: "2012-10-17 06:36:59">,
        @quantity=:@new_record>]},
   @key_items=false>,
 1=>
  {1=>
    #<Store id: 1, name: "it厨房", start_price_cents: 3400, fare_price_cents: 1000, average_time: nil, announcement: nil, image: "it.jpg", is_active: true, created_at: "2012-10-17 06:36:59", updated_at: "2012-10-17 06:36:59">}}

所以元帅一定是有些不对劲!

4

2 回答 2

0

你得到了ActionController::Session::CookieStore::CookieOverflow吗?

您可以将有限的数据保存到会话中(最大 3KB),所以我建议不要保存所有对象,而是保存它的主键,即id

我的意思是储蓄1而不是#<Dish id: 1, store_id: 1, name: "meat", count: 30, remaining_count: 30, price_cents: 1100, price_cents_currency: "CNY", image: nil, description: nil, created_at: "2012-10-11 07:38:26", updated_at: "2012-10-11 07:38:26">

于 2012-10-17T07:42:22.190 回答
0

原因可能是 disc.store 实际上是 Association 的实例,而不是 Store 的实例。@stale_state是关联的变量。

但是,Store.find_by_id(dish.store_id)返回一个真实的 Store 对象。

无论如何,将这些数据存储在会话中是一种不好的做法。

于 2012-10-17T08:28:48.720 回答