views:

983

answers:

4

Hello,

I have always been taught that storing objects in a session was a bad idea. Instead IDs should be stored that retrieve the record when needed.

However, I have an application that I wonder is an exception to this rule. I'm building a flashcard application, and the words being quizzed are in a table in the database whose schema doesn't change. I want to store the words currently being quizzed in a session, so a user can finish where they started in case they move on to a separate page.

In this case, is it possible to get away with storing these words as objects in the database? If so, why? The reason I ask is because the quiz is designed to move quickly, and I'd hate to waste a database call on retrieving a record that never changes in the first place. However, perhaps there are other negatives to a large session that I'm not aware of.

*For the record, I have tried caching it with the built-in memcache methods in Rails 2.3, but apparently that has a maximum size per item of 1MB.

+2  A: 

Rails tends to encourage RESTful design, and using sessions isn't very RESTful. I'd probably make a Quiz resource that has a bunch of words, as well as a current_word. This way, when they come back, you'll know where they were.

Now, REST isn't everything (depending on who you talk to), but there's a pretty good case against large sessions. Remember that sessions write things to and from disk, and the more data that you're writing, the longer it takes to read back...

Steve Klabnik
+1  A: 

Since your app is a Rails app, I would suggest either:

  1. Using your clients' ability to cache by caching the cards in javascript. (you'd need a fairly ajaxy app to do this, see the latest RailsCast for some interesting points on javascript page caching)
  2. Use one of the many other rails-supported server-side caching options (i.e. MemCached) to cache this data.
+7  A: 

The main reason not to store objects in the session is that if the object structure changes, you will get an exception. Consider the following:

class Foo
  attr_accessor :bar
end

class Bar
end

foo = Foo.new
foo.bar = Bar.new
put_in_session(foo)

Then, in a subsequent release of the project, you change Bar's name. You reboot the server, and try to grab foo out of the session. When it tries to deserialize, it fails to find Bar and explodes.

It might seem like it would be easy to avoid this pitfall, but in practice, I've seen it bite a number of people. This is just because serializing an object can sometimes take more along with it than is immediately apparent (this sort of thing is supposed to be transparent) and unless you have rigorous rules about this, things will tend to get flummoxed up.

The reason it's normally frowned upon is that it's extremely common for this to bite people in ActiveRecord, since it's quite common for the structure of your app to shift over time, and sessions can be deserialized a week or longer after they were originally created.

If you understand all that and are willing to put in the energy to be sure that your model does not change and is not serializing anything extra, you're probably fine. But be careful :)

Yehuda Katz
A: 

A much more insidious issue you'll encounter storing objects directly in the session is when you're using CookieStore (the default in Rails 2+ I believe). It's very easy to get CookieOverflow errors which are very hard to recover from.

Julian