Forum: Ruby on Rails has_many with :finder_sql question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Rich B. (Guest)
on 2006-01-06 23:22
(Received via mailing list)
hi all,

I have a Class, Client, which has_many projects (Project class).  the
projects depend on a session_id variable, however.  So the question
is, how can I do the following:

has_many :projects,
		 :finder_sql => "SELECT p.*  FROM projects p INNER JOIN
projects_users pu ON pu.project_id = p.id WHERE pu.user_id =
#{session[:user_id]}"

The problem is that I need to filter a client's projects using a
session variable, and the :finder_sql produces the error:

"undefined local variable or method `session' for Client:Class"

I thought that I could be sure the variable existed be creating a
default one in the initialize definition in the Client class, but that
doesn't work either.

Thanks!

rich
Justin F. (Guest)
on 2006-01-07 23:58
(Received via mailing list)
Rich B. wrote:

> session variable, and the :finder_sql produces the error:
>
> "undefined local variable or method `session' for Client:Class"
>
> I thought that I could be sure the variable existed be creating a
> default one in the initialize definition in the Client class, but that
> doesn't work either.

In general, Models shouldn't be aware of sessions. The session accessor
is a controller method.

I'm having trouble relating your SQL to your description - is it User or
Client that has the Projects, and is it has_many (which wouldn't require
a join table) or has_and_belongs_to_many (which would)?

Suppose a User has_many Projects, and you have the user id in the
session under the key :user_id.

If all you need to do is get the current user's projects, you should be
able to do something like this (untested) in a controller action:

   @user = User.find(session[:user_id])
   @projects = @user.projects

You don't need to specify the SQL in the model.

If you are worried about making two queries rather than one, you can use
the :include option to tell the find to include projects.

If this has to happen in many different actions, consider putting it in
a before filter in the controller.

Another point that may be useful - in the current version of Rails you
can also use find methods on collections, e.g.

   @project = @user.projects.find(proj_id)

This ensures that a user only sees his/her own projects, even if they
tamper with the id being passed back from the browser.

regards

   Justin
This topic is locked and can not be replied to.