2011-04-24 93 views
2

我創建了一個SessionHelper模塊看起來或多或少像這樣:存儲/在Rails餅乾檢索值

module SessionHelper 

    def create_cookie 
     cookies.signed[:token] = { 
     :value => [], 
     :expires => 1.hour.from_now 
     } 
    end 

    def cookie_values 
     cookies.signed[:token] 
    end 

    def add_value_to_cookie(value) 
     cookies[:token] << value 
    end 

    def cookie_exists? 
     cookies[:token].present? 
    end 

end 

然後,它被包括到應用控制器,並在過濾器時會觸發,每個請求之前:

create_cookie unless cookie_exists? 

我的網站不使用身份驗證,我想顯示客人創建的最近的項目。 因此,在項目控制器我有這樣的事情:

def create 
    @item=Item.new(params[:item]) 
    if @item.save 
    add_value_to_cookie(@item.id) 
    redirect_to @item 
    else 
    render :new 
    end 
end 

的問題如下:

  • 的前過濾器創建一個空 餅乾,我可以證實它的初始 值設爲到[](OK)
  • 用戶創建一個項目後,我期望cookie數組有一個額外的值,但相反它變成了無,並且沒有任何東西存在(BAD)。它甚至不會拋出異常。

我在哪裏發生了錯誤?我應該如何爲cookie添加新值? 此外,什麼是最好的方式來檢查cookie的存在?看起來#has_key?方法不可用。

一些副作用的問題:

因爲我想要顯示鏈接到客人的物品(存儲在cookie中),這將具有以下形式:

link_to @item.title, item_path(@item.id) 

我應該再只是使鏈接在#create動作中並將它們存儲在cookie中?還是應該按照我所知的方式保留ID,以生成它們?我很擔心,一個cookie可能無法以這樣的鏈接(因此我最初以爲存儲只是ID的)

由於事先存儲

編輯:看起來這是不可能使用一個cookie作爲數組,解決方法是使用某種形式的序列化。我對JSON

module SessionHelper 

    def set_user_cookie 
    cookies.signed[:token] = { 
     :value => [].to_json, 
     :expires => 1.hour.from_now 
    } 
    end 

    def user_cookie_values 
    load_user_cookie_data 
    end 


    def user_cookie_exists? 
     cookies[:token].present? 
    end 

    def add_to_user_cookie(value) 
    current = load_user_cookie_data 
    current << value 
    cookies.signed[:token] = current.to_json 
    end 

    def remove_from_user_cookie(value) 
    current = load_user_cookie_data 
    current.delete(value) 
    cookies.signed[:token] = current.to_json 
    end 

    private 

    def load_user_cookie_data 
    JSON.load(cookies.signed[:token]) 
    end 

end 

落戶雖然我仍然有興趣在聽什麼是存儲在cookie中的內容的首選方式。純ID或鏈接?

回答

1

如果項目模型不平凡,請不要將其加載到cookie中。有一個約2K的cookie限制和數據序列化將吃到很快。在任何情況下,應該對數據庫(或其他東西)進行持久化,並且只有最少量的會話狀態需要進入cookie。項目被創建到數據庫中。如果你想加載項目客戶端,使用JavaScript。

即使您有客人物品,只需將其加載到數據庫中並以某種方式標記即可。 IE:放入訪客表,或者有一個列設置guest = 1或有一個foreign_key到guest_items表或其他東西。真的(即使使用匿名身份驗證),會話只有當前的用戶ID(在您的情況下,沒有任何內容)。我假設你正試圖堅持永久性cookies來「記住我」類型的功能,那很好。抽象層有點奇怪。簡單系統中的首選方式是:

# in controller, bad idea 
cookies['items'] << Item.new("whatever") 

堅持數據庫,只將會話存儲在cookie中。