在Rails cookie中存储/检索值

我创建了一个SessionHelper模块,看起来或多或少是这样的:

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 

然后它被包含到Application控制器中,并在每个请求之前在filter中被触发:

 create_cookie unless cookie_exists? 

我的网站不使用身份validation,我想显示最近由访客创建的项目。 所以,在一个Item控件中我有这样的东西:

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

问题如下:

  • 前filter创建一个空cookie,我可以确认它的初始值设置为[](OK)
  • 在用户创建一个项目后,我希望cookie数组有一个额外的值,但它会变成一个Nil,并且不存在任何内容(BAD)。 它甚至没有抛出exception。

我在哪里犯了错误? 我应该如何向cookie添加新值? 此外,检查cookie存在的首选方法是什么? 看来#has_key? 方法不可用。

一些方面的问题:

因为我想显示客人项目的链接(存储在cookie中),其forms为:

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

我应该只在#create动作中创建链接并将它们存储在cookie中吗? 或者我应该保留我所知道的ID,来生成它们? 我担心cookie可能无法存储这样的链接(因此我最初想到只存储ID)

提前致谢

编辑:似乎不可能将cookie用作数组,解决方法是使用某种forms的序列化。 我选择了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或链接?

我最近遇到了类似的问题并通过创建一个隐藏所有cookie哈希交互的CookieCollection类来解决它,并允许您像使用Array一样从集合中添加和列出。 它通过控制器方法和帮助程序公开。

http://www.swards.net/2013/08/cookie-collection-objects.html

如果Item模型不重要,请不要将其加载到cookie中。 有大约2k的cookie限制,数据的序列化将很快进入。 在任何情况下,都应该对数据库(或其他东西)进行持久化,并且只需要将最少量的会话状态放入cookie中。 项目被创建到数据库中。 如果要加载项目客户端,请使用javascript。

即使您有来宾项目,只需将其加载到数据库中并以某种方式标记它。 IE:放入一个guest表,或者有一个设置guest = 1的列或者有一个foreign_key到guest_items表或其他东西。 实际上(即使使用匿名身份validation),会话只具有当前用户ID(在您的情况下,没有任何内容)。 我假设你试图坚持使用永久性cookie来“记住我”类型的function,这很好。 抽象层有点奇怪。 简单系统中的首选方法是:

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

持久存储数据库,仅将会话存储在cookie中。