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.