# @session's scope in the model

**URL:** <https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187>\
**Category:** Rails\
**Created:** [September 1, 2006, 11:09am UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187 "2006-09-01T11:09:00Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![harp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ecd19e/32.png) [@harp](https://www.ruby-forum.com/u/harp)\
**Post date:** [September 1, 2006, 11:09am UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187/1 "2006-09-01T11:09:00Z")

</div>

for some very annoying reason, the @session variable isn’t recognized in  
the model. i have a acl login system, and the user that is logged in has  
a @session[‘user’] parameter, which checks to see if he’s logged in  
(==1) or logged out (==0).  
why isn’t this recognized in the model:

if @session[‘user’]==1  
…  
else  
…  
end

((it returns an error nil[]!))

and when i tried  
session[‘user’]  
or even just  
session

((it states undefined local variable session))

it didn’t work either.  
am i missing something stupid, or have i looked over some important  
issue, that i haven’t quite understood?  
thanks for any insights/help.

harp

---

<div class="post-metadata">

**Author:** ![harp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ecd19e/32.png) [@harp](https://www.ruby-forum.com/u/harp)\
**Post date:** [September 1, 2006, 1:32pm UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187/2 "2006-09-01T13:32:39Z")

</div>

harp wrote:

> for some very annoying reason, the @session variable isn’t recognized in  
> the model.

You’re not missing anything–the session should be used in the  
controller and is not available in the model on purpose. If you give an  
example of what you are trying to do in the model, we may be able to  
point you in the right direction.

---

<div class="post-metadata">

**Author:** ![harp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ecd19e/32.png) [@harp](https://www.ruby-forum.com/u/harp)\
**Post date:** [September 3, 2006, 10:32am UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187/3 "2006-09-03T10:32:23Z")

</div>

> If you give an  
> example of what you are trying to do in the model, we may be able to  
> point you in the right direction.

Thanks for the reply…i wanted to give the admin of the site a  
possibility to see the pages that were marked unpublished, that for  
regular users, were impossible to see.

((publish - tinyint(1) column for any page in the Page model, that  
marks whether the page is published or unpublished. only the published  
are seen by everyone))

to do this, i found a great (with\_scope) method, that gives me exactly  
what i wanted,

```
def self.find(*args)
    	if !@session['user'] ### errors populated here
		self.with_scope(:find => { :conditions => "publish=1" }) do
		super(*args)
			end
	else
		super(*args)
	end
end

```

except, now i get nil errors from the session variable in the first part  
of the clause. how do get this working, if i need to check the session  
to see if it is the admin, but can’t use the session in the model?  
can/should this be defined in the controller?  
either way, much appreciation your way…thanks,

harp

---

<div class="post-metadata">

**Author:** ![harp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ecd19e/32.png) [@harp](https://www.ruby-forum.com/u/harp)\
**Post date:** [September 4, 2006, 3:44am UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187/4 "2006-09-04T03:44:31Z")

</div>

harper wrote:

> > If you give an  
> > example of what you are trying to do in the model, we may be able to  
> > point you in the right direction.
> 
> Thanks for the reply…i wanted to give the admin of the site a  
> possibility to see the pages that were marked unpublished, that for  
> regular users, were impossible to see.  
> …  
> harp

Hi Harp, I’m a newbie, but I’ll go ahead and attempt an answer. I  
believe that what you are running into here is the MVC separation  
preventing you from writing something that might turn into spaghetti  
code. The idea is that each model should know everything there is to  
know about its data, and nothing else.

I think the solution you seek will involve putting some of the smarts in  
either the controller, or perhaps the view. It seems like the code you  
included in your last post was in a “pages” model? If so, it can stay  
there, but the “logged\_in” parameter would be passed into it by the  
controller or view code that is trying to get this data from the pages  
model.

In short, you don’t want the pages model to know anything about users,  
and vice versa. The controller can ask the user about a user stuff and  
can ask for stuff from a pages model. If there is something about a  
user that affects the results of pages, it needs to be passed in as a  
parameter to the pages model method, rather than divined within the  
pages model.

hth,  
jp

---

<div class="post-metadata">

**Author:** ![harp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ecd19e/32.png) [@harp](https://www.ruby-forum.com/u/harp)\
**Post date:** [September 4, 2006, 9:52am UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187/5 "2006-09-04T09:52:16Z")

</div>

…

> included in your last post was in a “pages” model? If so, it can stay  
> there, but the “logged\_in” parameter would be passed into it by the  
> controller or view code that is trying to get this data from the pages  
> model.

first of firsts, thanks for the reply. (yes, it is much appreciated).  
i suppose there is good reasoning for why the session isn’t availiable  
in the model (makes perfect sense after the short explination).  
the current minor-problem on my mind now, is the reasoning of why i am  
defining this in the model.  
the initial thought behind ‘improving’ the find method (for the pages  
class) populated from the DRY principle i am working on every day - - i  
could have went to each place i was using find in the pages controller  
(that’s where i’m using the find method) and added a [:conditions =\>  
‘publish=1’] but it seemed a lot more aesthetic and cleaner to use  
:with\_scope, and avoid going to EACH place i was using the find method  
(quite a couple) and adding that.  
either way, i suppose passing a parameter is cleaner than writing

if @session  
find… long+published=1  
else  
find…long

so how do i pass a parameter in the find method? find(:all, :conditions,  
:options, :logged\_in =\> true/false)? won’t it populate an error  
'unrecognized symbol/etc? any conventions on how to do this?  
(many thanks for the reply)

harp

---

<div class="post-metadata">

**Author:** ![harp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ecd19e/32.png) [@harp](https://www.ruby-forum.com/u/harp)\
**Post date:** [September 4, 2006, 2:43pm UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187/6 "2006-09-04T14:43:35Z")

</div>

harper wrote:

> marks whether the page is published or unpublished. only the published  
> else  
> harp
> 
> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

There are a couple of plugins floating around that also need to pull  
the user id from the session, so far i’ve seen two ways to do it.

The first is to put a before\_filter in the Application controller that  
sets a User class variable to the current user id. The other uses a  
Thread local variable.

The first one works fine in most cases, but would probably break if  
Rails ever becomes threaded.

class User  
cattr\_accessor :current\_user  
…  
end

— application.rb —  
before\_filter :set\_current\_user

def set\_current\_user  
User.current\_user = session[‘user’]  
end

The current user will get set at the beginning of each request, so you  
can be sure that it will be correct.

\_Kevin

---

<div class="post-metadata">

**Author:** ![harp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ecd19e/32.png) [@harp](https://www.ruby-forum.com/u/harp)\
**Post date:** [September 4, 2006, 11:01am UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187/7 "2006-09-04T11:01:17Z")

</div>

> so how do i pass a parameter in the find method? find(:all, :conditions,  
> :options, :logged\_in =\> true/false)? won’t it populate an error  
> 'unrecognized symbol/etc? any conventions on how to do this?  
> (many thanks for the reply)
> 
> harp

i’ve been trying for two-three hours, and i can’t get this to work!  
how do i pass another option/arg/parameter in the def find method?

find(\*args, session) doesn’t work, it gives me a parse error…any other  
variation doesn’t seem to work either…the only way it doesn’t give me  
an error is if i do  
find(args, session) but then it only uses one option, and errors on  
:include, :otheroptions etc.

is there a finer correct syntax i’m missing?  
thanks for any help…

---

<div class="post-metadata">

**Author:** ![harp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/ecd19e/32.png) [@harp](https://www.ruby-forum.com/u/harp)\
**Post date:** [September 4, 2006, 4:27pm UTC](https://www.ruby-forum.com/t/sessions-scope-in-the-model/67187/8 "2006-09-04T16:27:31Z")

</div>

> class User  
> cattr\_accessor :current\_user  
> …  
> end
> 
> — application.rb —  
> before\_filter :set\_current\_user
> 
> def set\_current\_user  
> User.current\_user = session[‘user’]  
> end
> 
> The current user will get set at the beginning of each request, so you  
> can be sure that it will be correct.
> 
> \_Kevin

…sorry for being a little slow; so how does this connect to the

self.find(\*args)  
with\_scope =\> …

that i need to define? when i put the above code in the controller, it  
failed too(the model as well), as any definition in the Class Page,  
doesn’t accept the session variable.  
how am i supposed to connect the User.current\_user to the above?

def set\_current\_user = session[‘user’]  
…  
end

self.find(\*args)  
if set\_current\_user  
with\_scope =\> …  
else  
…  
end

how do i check the session in a class-function?  
?

def self.find(\*args)  
if !@session[‘user’] ### errors populated here  
self.with\_scope(:find =\> { :conditions =\> “publish=1” }) do  
super(\*args)  
end  
else  
super(\*args)  
end  
end

any help, much appreciated. really.  
thanks,

harp
