views:

145

answers:

1

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.

+1  A: 

You might be able to set up a link between users and sites, with a :through relationship.

Does the code you have provided work? Is there an error that occurs?

Toby Hede
I have tried dozens of solutions, ranging from many different errors. For example, I tried creating three named_scopes and then referencing them in controller: super.current_user(:contact_id).contacts(:contactable_id, :contactable_type).site_staff_limit(:site_id)But this gives a no association error.
JohnMerlino
Hang on ... it looks like you are trying to call a scope on the controller using "super"?
Toby Hede
yes super contains the students information. It is inherited from a method in the restfulcontroller created in the lib directory, where the students controller inherits from. So super refers to student model.
JohnMerlino
So your model is inheriting from the controller?
Toby Hede
StudentsController is inheriting the keyword super from Restful Controller. Then I am applying a named_scope onto super to limit results. Super contains all the records. I want to limit by the site_id of the current_user.
JohnMerlino
OK, I am terribly confused and not much help. How can you put a named scope on a controller?
Toby Hede
JohnMerlino