Storing ActiveRecords in the Session


#1

Is there a secret to successfully storing ActiveRecords in the Session
(which is being stored in the DB) without getting marshalling
exceptions?


#2

just store the primary key of the record… that’s usually much better

2007/1/26, Robert H. removed_email_address@domain.invalid:


#3

On Jan 26, 2007, at 1:57 PM, Robert H. wrote:

Peter E. wrote:

just store the primary key of the record… that’s usually much
better

Sure, but then I have to hit the DB every time I use it, no?

No, it’s relatively easy to make sure the ‘penalty’ is once per page
that uses it.

The session is likely a DB hit in any case (ActiveRecordStore), and
if you put an
entire AR model in it, it makes this session DB hit a monster each
and every page.

Storing the ID makes sure that your AR model isn’t stale, too.


– Tom M., CTO
– Engine Y., Ruby on Rails Hosting
– Reliability, Ease of Use, Scalability
– (866) 518-YARD (9273)


#4

Peter E. wrote:

just store the primary key of the record… that’s usually much better

Sure, but then I have to hit the DB every time I use it, no?


#5

Tom M. wrote:

On Jan 26, 2007, at 1:57 PM, Robert H. wrote:

Peter E. wrote:

just store the primary key of the record… that’s usually much
better

Sure, but then I have to hit the DB every time I use it, no?

No, it’s relatively easy to make sure the ‘penalty’ is once per page
that uses it.

OK, exactly. So, what is the “relatively easy” way to make sure the
object is only loaded once per page?

  • Still perplexed

#6

On Jan 31, 2007, at 12:28 PM, Robert H. wrote:

No, it’s relatively easy to make sure the ‘penalty’ is once per page
that uses it.

OK, exactly. So, what is the “relatively easy” way to make sure the
object is only loaded once per page?

  • Still perplexed


Posted via http://www.ruby-forum.com/.

def current_user
@current_user ||= session[:user_id] ? User.find_by_id(session
[:user_id]) : nil
end

This will cache the the user in @current_user so you can call
current_user multiple times during a request and it will only hit the
db once.

Cheers-
– Ezra Z.
– Lead Rails Evangelist
– removed_email_address@domain.invalid
– Engine Y., Serious Rails Hosting
– (866) 518-YARD (9273)


#7

On Jan 31, 5:51 pm, Ezra Z. removed_email_address@domain.invalid wrote:

just store the primary key of the record… that’s usually much

  • Still perplexed
    current_user multiple times during a request and it will only hit the
    db once.

This reminds me of something similar, suppose on sign up or in some
form the user has to fill in 20 or 30 fields and send them to the
server. The server validates them and creates a record on the
database. However, suppose that there is some complex logic that needs
to validate the form data beyond some simple stuff you could do
through javascript, perhaps you could do some sort of AJAX thing, but
the other possibility seems to be to store the form fields in the
session because the record may not get created on the database if
there is a problem, but you don’t want the user to have to fill the
fields all in again. I did it that way previously before I had done
much AJAX, but then I realized the session uses alot of space on the
file system.


#8

Ezra Z. wrote:

def current_user
@current_user ||= session[:user_id] ? User.find_by_id(session
[:user_id]) : nil
end

This will cache the the user in @current_user so you can call
current_user multiple times during a request and it will only hit the
db once.

– Ezra Z.

I’ll try that again, but, IIRC, the last time I tried it, I was getting
marshaling problems when saving the object for some reason.

Thanks.


#9

On Jan 31, 2007, at 4:10 PM, Robert H. wrote:

db once.

– Ezra Z.

I’ll try that again, but, IIRC, the last time I tried it, I was
getting
marshaling problems when saving the object for some reason.

Thanks.

Don’t save the whole object thats the entire point. Just save the
objects id in the session. That method will use the id to do a db
lookup and then cache the results.

– Ezra Z.
– Lead Rails Evangelist
– removed_email_address@domain.invalid
– Engine Y., Serious Rails Hosting
– (866) 518-YARD (9273)


#10

Ezra Z. wrote:

Don’t save the whole object thats the entire point. Just save the
objects id in the session. That method will use the id to do a db
lookup and then cache the results.

To clarify, the question is what class your suggested code lives in.

When I created instance variables (where you are caching the object) in
a model class, saving the record generated marshaling exceptions.

An example like your current_user method looks like it would probably
live in a controller or helper and therefore not be saved and not create
a problem.

Should I be able to drop ActiveRecord objects into instance variables in
another ActiveRecord instance without getting marshaling problems? I
should test again, but that is contrary to my experience.


#11

surf wrote:

much AJAX, but then I realized the session uses alot of space on the
file system.

I would try this:

  • database table with a ‘committed’ boolean
  • uncommitted records are disposable
  • committed records are transactable
  • build a Model out of the table with no validators
  • inherit a class, Q, from that Model & add validators
  • paint the form with the Model & submit it
  • to commit, copy the attributes into an instance of Q
  • set the committed bit, and try to save

I don’t know if each detail there would work, or cause problems. But in
general the point of OO is to abstract the thing that varies, so if the
validators are the issue you should arrange to move them out of the way,
instead of working around them. A user with a partly committed form
should
be able to return to it.


Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!


#12

Take a look at object_id_session plugin from Yurii R.:

http://rashkovskii.com/articles/2007/1/2/object_id_session


Aníbal Rojas
http://www.rubycorner.com
http://www.hasmanydevelopers.com