# Dynamically set named\_scope based on current\_user

**URL:** <https://www.ruby-forum.com/t/dynamically-set-named-scope-based-on-current-user/182354>\
**Category:** Ruby\
**Created:** [January 27, 2010, 12:00am UTC](https://www.ruby-forum.com/t/dynamically-set-named-scope-based-on-current-user/182354 "2010-01-27T00:00:03Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [January 27, 2010, 12:00am UTC](https://www.ruby-forum.com/t/dynamically-set-named-scope-based-on-current-user/182354/1 "2010-01-27T00:00:03Z")

</div>

Hey all,  
I keep getting the following error:

You have a nil object when you didn’t expect it!  
You might have expected an instance of Array.  
The error occurred while evaluating nil.size

Based on the current user, when they navigate to a page, I want to limit  
them to what they can see based on their site. Problem is there is no  
association between site and user table directly. A contact has\_one user  
(user information is stored in current\_user variable). A site has\_many  
contacts. And a site has\_many students, where students table has a  
foreign key of site\_id. So there is a link between students and site, so  
when the current user navigates to students page, they can only see  
students from same site as them. I can do this by hard coding a number  
in a named\_scope to only display students for the site of the  
current\_user. But different users will belong to different sites so when  
logged in, the site their associated with will change. That’s the  
problem - to dynamically set that value in a named\_scope. This is what I  
have:

StudentsController

def index\_scoper  
if current\_user.role\_id == 8  
super.site\_staff\_limit while current\_user[:site\_id] #The problem is  
the user table has no site\_id. There is no direct link between the users  
table and sites table. However, there is a link between users and  
contacts and then site and contacts and then site and students, where  
students table has site\_id.  
else  
super.with\_state.with\_site  
end  
end

Student Model  
named\_scope :site\_staff\_limit, lambda {|site\_id| {:conditions =\>  
{:site\_id =\> site\_id}}}

Thanks for any suggestions.

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [January 27, 2010, 12:52am UTC](https://www.ruby-forum.com/t/dynamically-set-named-scope-based-on-current-user/182354/2 "2010-01-27T00:52:52Z")

</div>

John M. wrote:

> Hey all,  
> I keep getting the following error:
> 
> You have a nil object when you didn’t expect it!  
> You might have expected an instance of Array.  
> The error occurred while evaluating nil.size
> 
> Based on the current user, when they navigate to a page, I want to limit  
> them to what they can see based on their site. Problem is there is no  
> association between site and user table directly. A contact has\_one user  
> (user information is stored in current\_user variable). A site has\_many  
> contacts. And a site has\_many students, where students table has a  
> foreign key of site\_id. So there is a link between students and site, so  
> when the current user navigates to students page, they can only see  
> students from same site as them. I can do this by hard coding a number  
> in a named\_scope to only display students for the site of the  
> current\_user. But different users will belong to different sites so when  
> logged in, the site their associated with will change. That’s the  
> problem - to dynamically set that value in a named\_scope. This is what I  
> have:
> 
> StudentsController
> 
> def index\_scoper  
> if current\_user.role\_id == 8  
> super.site\_staff\_limit while current\_user[:site\_id] #The problem is  
> the user table has no site\_id. There is no direct link between the users  
> table and sites table. However, there is a link between users and  
> contacts and then site and contacts and then site and students, where  
> students table has site\_id.  
> else  
> super.with\_state.with\_site  
> end  
> end
> 
> Student Model  
> named\_scope :site\_staff\_limit, lambda {|site\_id| {:conditions =\>  
> {:site\_id =\> site\_id}}}
> 
> Thanks for any suggestions.

relationship between tables:

users: contact\_id  
contact: primary key, contactable\_id, contactable\_type  
site: primary key  
student: site\_id

User model  
belongs\_to :contact

Contact model  
has\_one :user  
belongs\_to :contactable, :polymorphic =\> true, :dependent =\> :destroy

Site model  
has\_many :contacts, :as =\> :contactable  
has\_many :students

Students model  
belongs\_to :site

This successfully limits the students by site:  
StudentsController  
def index\_scoper  
if current\_user.role\_id == 8  
super.site\_staff\_limit  
else  
super.with\_state.with\_site  
end  
end

Students model  
named\_scope :site\_staff\_limit, :conditions =\> {:site\_id =\> 1}

The problem is different users will belong to different sites, so they  
can only access student records of the site they belong to. I am having  
difficulty making that named\_scope above dynamic enough to accomplish  
this.

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [January 27, 2010, 12:25pm UTC](https://www.ruby-forum.com/t/dynamically-set-named-scope-based-on-current-user/182354/3 "2010-01-27T12:25:57Z")

</div>

On 27.01.2010 00:52, John M. wrote:

> The problem is different users will belong to different sites, so they  
> can only access student records of the site they belong to. I am having  
> difficulty making that named\_scope above dynamic enough to accomplish  
> this.

Since I suspect this is a Rails app, you will have better success when  
asking the Rails community:

> **[Community](https://rubyonrails.org/community)**
>
> A web-app framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern.

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [January 27, 2010, 2:58pm UTC](https://www.ruby-forum.com/t/dynamically-set-named-scope-based-on-current-user/182354/4 "2010-01-27T14:58:05Z")

</div>

John M. wrote:

> That’s the  
> problem - to dynamically set that value in a named\_scope.

Don’t use a named scope; create an anonymous scope dynamically.

class ApplicationController  
def students(staff\_id = session[:staff\_id])  
Student.scoped(:conditions =\> {:staff\_id =\> staff\_id})  
end  
end

@students = students.find(…)

Or you can make a helper method using with\_scope.

---

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [January 27, 2010, 2:59pm UTC](https://www.ruby-forum.com/t/dynamically-set-named-scope-based-on-current-user/182354/5 "2010-01-27T14:59:22Z")

</div>

Or you can pass arguments to a named scope: see

[http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality](http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality)
