0

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.

JohnMerlino
  • 3,900
  • 4
  • 57
  • 89

1 Answers1

1

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
  • 36,755
  • 28
  • 133
  • 162
  • 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 Jan 26 '10 at 23:57
  • Hang on ... it looks like you are trying to call a scope on the controller using "super"? – Toby Hede Jan 27 '10 at 00:11
  • 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 Jan 27 '10 at 00:34
  • So your model is inheriting from the controller? – Toby Hede Jan 27 '10 at 04:37
  • 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 Jan 27 '10 at 13:18
  • OK, I am terribly confused and not much help. How can you put a named scope on a controller? – Toby Hede Jan 27 '10 at 21:25
  • No, the named_scope is in students model: named_scope :contactable, lambda { |current_user| case when current_user.contact.contactable_id = 1 && current_user.contact.contactable_type = 'site' then { :conditions => {:site_id => 1}} else nil end } I'm trying to filter so only students from same site can view student records. – JohnMerlino Jan 27 '10 at 21:36