Forum: Ruby on Rails has_many :through scope on join attribute

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.
Daniel -. (Guest)
on 2006-05-10 18:00
(Received via mailing list)
Hi

I have a has_many :through.  It's a basic mapping of

Project
id
....

User
id
....

TeamMembers
project_id
user_id
role


What I would like to do is have different roles so I can have in the
project
model

has_many :core_members, :through => :team_members, :source => :user

but I would like to limit this to only those with the "core" role in the
team members table for this project.

Any ideas?
Bosko M. (Guest)
on 2006-05-10 20:21
(Received via mailing list)
On 5/10/06, Daniel N <removed_email_address@domain.invalid> wrote:
[...]
> What I would like to do is have different roles so I can have in the project
> model
>
> has_many :core_members, :through => :team_members, :source => :user
>
> but I would like to limit this to only those with the "core" role in the
> team members table for this project.
>
> Any ideas?

You can specify :conditions in your has_many statement.  So for example:

has_many :core_members, :through => :team_members, :source => :user,
    :conditions => "team_members.role = 'core'"

or similar.

--
Bosko M. <removed_email_address@domain.invalid>
Daniel -. (Guest)
on 2006-05-11 03:22
(Received via mailing list)
Thanx Bosko,  That worked great.

I have one question for this tho...

How do I have a has_one for this situation where the role is leader?

ie each project only has_one :leader

but I can't specify the through condition.

I don't really want to put a leader_id field in the projects table.  I
would
like to keep all team members regardless of their role in the
team_members
table.

Any ideas how I could do this?  I have tried for quite a few hours now
and
the only way I have found to impelment it is to write my own leader and
leader= methods in the project model.
Josh S. (Guest)
on 2006-05-11 09:11
Bosko M. wrote:
> On 5/10/06, Daniel N <removed_email_address@domain.invalid> wrote:
>> What I would like to do is have different roles so I can have in the project
>> model
>>
>> has_many :core_members, :through => :team_members, :source => :user
>>
>> but I would like to limit this to only those with the "core" role in the
>> team members table for this project.
>>
>> Any ideas?
>
> You can specify :conditions in your has_many statement.  So for example:
>
> has_many :core_members, :through => :team_members, :source => :user,
>     :conditions => "team_members.role = 'core'"
>
> or similar.

That works just fine, but I like to do it with a special association in
the join model, then use that as the :source in the containing model.
That localizes the condition to the proper scope, allows potential
reuse, and best of all you don't have to name the table in the
:conditions. I have a full example of that on my blog (and the :uniq
stuff might be useful in this situation as well):
http://blog.hasmanythrough.com/articles/2006/05/06...

By the way, Daniel, there is no has_one :through association.

--
Josh S.
http://blog.hasmanythrough.com
Daniel -. (Guest)
on 2006-05-11 09:34
(Received via mailing list)
Hi Josh,

Thanx for the eplaination.  I've been to your blog.  I have found it
very
useful.  Thanx.  I have read your article that you mentioned but it must
of
been too late or something because I just couldn't quite get my head
around
the relationships that you had.  Also I don't have the uniq option.  I'm
assuming that this is only available for those on the edge.
Josh S. (Guest)
on 2006-05-11 19:55
Daniel ----- wrote:
> Hi Josh,
>
> Thanx for the eplaination.  I've been to your blog.  I have found it
> very
> useful.  Thanx.  I have read your article that you mentioned but it must
> of
> been too late or something because I just couldn't quite get my head
> around
> the relationships that you had.  Also I don't have the uniq option.  I'm
> assuming that this is only available for those on the edge.

Right, :uniq is only on edge at the moment. However, for now you can
still use the DISTINCT keyword in your :select if you need to remove
duplicates.

Did you manage to grok what I was doing in those associations? I'm
moving the condition into the association in the join model, which from
an object-oriented perspective is the right place to put it. You know,
data-hiding and encapsulation and all that. If you're curious what's
going on you should look at the generated SQL in development.log.

--
Josh S.
http://blog.hasmanythrough.com
Daniel -. (Guest)
on 2006-05-12 05:26
(Received via mailing list)
Hi Josh,

I can decipher what you have done but I don't think that I understand it
well enough to know when to use it yet.  I'll have a play with it.

Would there be a way to specify a validates_uniqueness_of :author

in your example to have only one author per book?  Would something like

validates_uniqueness_of :author, :scope => 'book_id', :if Proc.new{
self.role = 'author' }

make it so that there could only be one author per book?
Josh S. (Guest)
on 2006-05-13 03:58
Daniel ----- wrote:
> I can decipher what you have done but I don't think that I understand it
> well enough to know when to use it yet.  I'll have a play with it.
>
> Would there be a way to specify a validates_uniqueness_of :author
> in your example to have only one author per book?  Would something like
>
> validates_uniqueness_of :author, :scope => 'book_id', :if Proc.new{
> self.role = 'author' }
>
> make it so that there could only be one author per book?

Yes, something like that validation should work, though you want == (not
=) in the proc, and I think you'll need to change :author to user_id.
You might need to tweak something else, I haven't built one of these
before.

--
Josh S.
http://blog.hasmanythrough.com
This topic is locked and can not be replied to.