我一直被教导在会话中存储对象是一个坏主意.而是应该存储ID,以便在需要时检索记录.
但是,我有一个应用程序,我想知道这个规则的例外.我正在构建一个flashcard应用程序,被测试的单词位于数据库的表中,其架构不会更改.我想在会话中存储当前正在进行测验的单词,以便用户可以在他们进入单独页面的情况下完成他们开始的位置.
在这种情况下,是否可以将这些单词作为对象存储在数据库中?如果是这样,为什么?我问的原因是因为测验的目的是快速移动,而且我讨厌在检索永远不会改变的记录时浪费数据库调用.但是,对于我不了解的大型会话,可能还有其他负面影响.
*为了记录,我尝试使用Rails 2.3中的内置memcache方法缓存它,但显然每个项目的最大大小为1MB.
不在会话中存储对象的主要原因是,如果对象结构发生更改,您将获得异常.考虑以下:
class Foo attr_accessor :bar end class Bar end foo = Foo.new foo.bar = Bar.new put_in_session(foo)
然后,在项目的后续版本中,您更改Bar的名称.您重新启动服务器,并尝试从会话中抓取foo.当它试图反序列化时,它无法找到Bar并爆炸.
看起来似乎很容易避免这个陷阱,但在实践中,我看到它咬了很多人.这只是因为序列化一个对象有时可能会比它更明显(这种事情应该是透明的),除非你有严格的规则,否则事情往往会变得黯然失色.
它通常不赞成的原因是,在ActiveRecord中咬人是非常常见的,因为应用程序的结构随着时间的推移而变化很常见,并且会话可以在最初创建后一周或更长时间内反序列化.
如果您了解所有这些并且愿意投入精力来确保您的模型不会改变并且没有额外的序列化,那么您可能会很好.不过要小心 :)
Rails倾向于鼓励RESTful设计,并且使用会话不是非常RESTful.我可能会制作一个包含大量单词的Quiz资源,以及一个current_word.这样,当他们回来时,你会知道他们在哪里.
现在,REST不是一切(取决于你与谁交谈),但是对于大型会话来说这是一个相当不错的案例.请记住,会话在磁盘上写入内容,并且您正在编写的数据越多,回读所需的时间就越长......