views:

54

answers:

3

I have statements such as @user = User.find(current_user.id) throughout my app.

Sometimes a user might enter with a nil variable (such as a new user for whom current_user is nil).

I'm sure the dumb way to do this would be to scatter if statements everywhere like...

if current_user.exists?
  @user = User.find(current_user.id)
else
  redirect_to root_url
  ---*or*---
  @user = "new"   # for use with if/case statements later on
end

What is the elegant way to deal with this confusion?

A: 

Assuming the language you're using is object oriented, I would create an object that holds the current user context. By default you could use a CurrentUserContext instance for uknown users that have very limited access.

When users login, you can load all user information and security information into a new instance of CurrentUserContext.

It's just a rough idea, but maybe it helps.

edit: This way you wouldn't need to create all kind of security exception rules... You just assume the security settings of the current context instance and ajust application behaviour according to that.

Laurens Ruijtenberg
@Laurens: You can find the language from the tags attached to the question, in this case Ruby on Rails. Thanks very much for your answer.
sscirrus
A: 

To get nils when there is no current user:

@user = current_user && User.find(current_user.id)

To get "new" when there is no current user:

@user = current_user ? User.find(current_user.id) : 'new'

Neither really solves the problem, but now at least it's on one line. For a more general, solution, perhaps you should scrap the current_user variable.

raylu
A: 

@user = User.find(current_user.id) is a little unnecessary. Mostly because current_user is a User object already, so at the very least you should do @user = current_user, but I would recommend that if it isn't already done by the authentication framework, I would add this to you application controller:

helper_method :current_user

That will make the current_user object available to your views and render the @user object unnecessary.

For handling redirects, I usually have this in my application controller:

before_filter :require_login

def require_login
   current_user || redirect_to(root_url)
end

And then in my controllers that don't want to redirect:

skip_before_filter :require_login

Regarding setting the user to new, I wouldn't do it. I generally like my User objects to be user objects. I would just test for a new user by if current_user where a nil current_user is the same as setting it to 'new'.

I hope this helps

Geoff Lanotte
Awesome! Thanks a lot Geoff.
sscirrus