Rich Brant wrote:
> 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.
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