if a && a.something...

jack wrote the following on 30.09.2006 23:32 :

Ok, so I'm lazy, and something about always checking to see if an object exists before calling one of its methods just strikes me as fairly...'mundane'?

In particular, I often do this in code:

if session['user] && session['user'].is_admin ... end

I'd really just like to be able to drop of the session['user'] check. I mean, if the object doesn't even exist, then the method call can't run, and the whole thing should probably evaluate to nil, right?

For this kind of things I use a SessionHelper module which the ApplicationHelper and ApplicationController include. In the SessionHelper I put things like :

module SessionHelper     def current_user        return @cached_user if @cached_user        session[:user_id] ? (@cached_user = User.find(:first,                                                      :conditions => [ 'id = ?',                                                             session[:user_id]])) : nil     end     def is_admin?        current_user && current_user.is_admin?     end end

Then you can use

if is_admin? ... end

I never store objects in session, only objects' ids to avoid nasty problems. This is the reason behind the "@cached_user", which effectively limits current user SQL queries to one by request.

I'm just wondering if there's a smarter way to go about situations like this.

Simply apply some DRY to your code :slight_smile:

Lionel

First off, let me state that I haven't stored a user object in the session in over a year. So I'm just pointing out two things that I remember :slight_smile:

The first one is a development issue. Say you're playing with your app in the web browser, and you've logged in. Then you make a change, any change, to the User model. The next request that you make will blow up. As I said, it's been over a year, so I don't know if that's still the case. I can't see why it would have changed though.

The next one is an issue of stale session data. If you store the entire user in the session, but update it in the db elsewhere (perhaps the admin modified the user or something), then the session data won't reflect that. Imagine I'm using your site, and you decide I'm a bad person and disable my account. If the user data is in the session, my account won't truly be disabled until the next time my info's looked up from the db - e.g. my session expires and I try to log back in.

Pat

Pat Maddox wrote the following on 01.10.2006 00:29 :

  

hehe, nicely done Lionel. I'll have to give this a try. Thanks for the thoughts! Btw, what kind of nasty problems are you referring to?      First off, let me state that I haven't stored a user object in the session in over a year. So I'm just pointing out two things that I remember :slight_smile:

The first one is a development issue. Say you're playing with your app in the web browser, and you've logged in. Then you make a change, any change, to the User model. The next request that you make will blow up. As I said, it's been over a year, so I don't know if that's still the case. I can't see why it would have changed though.    +1: the object itself is serialized and most of the time can't match the updated class when you try to de-serialize it -> the whole session is blown.

The next one is an issue of stale session data. If you store the entire user in the session, but update it in the db elsewhere (perhaps the admin modified the user or something), then the session data won't reflect that. Imagine I'm using your site, and you decide I'm a bad person and disable my account. If the user data is in the session, my account won't truly be disabled until the next time my info's looked up from the db - e.g. my session expires and I try to log back in.    Most of the time I'm with you on this one: I don't like changes made somewhere in an application not being reflected in the whole application. There are cases though where objects in session can make sense (sometimes you need temporary objects that don't *have* to be stored outside of a session context, the question of putting them in the database then must seek an answer on a case-by-case basis depending on the specific advantages/drawbacks for the case at hand).

Lionel.