使用session来存储我的购物车

时间:2012-10-17 07:28:35

标签: ruby-on-rails session

我有2个型号:

Store has_many :dishes

Dish belong_to :store

我用会话来存储我的购物车:

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,会话[: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">}}

所以元帅必定有些错误!

2 个答案:

答案 0 :(得分: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">

答案 1 :(得分:0)

原因可能是dish.store实际上是Association的一个实例,而不是Store的实例。 @stale_state是Association的变量。

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

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