[Dbix-class] Naming columns in nested joins

Matt S Trout dbix-class at trout.me.uk
Wed May 24 13:57:33 CEST 2006


Jon wrote:
> Hi,
> 
> I'm doing a nested with three tables:
> 
> member: (has_many member_books mb)
> member_id
> 
> member_books (belongs to member, book)
> member_id
> book_id
> relation
> 
> book (has many member_books mb)
> book_id
> 
> 
> My query I'm running is "What (distinct) books does members who wants 
> the book the current member has have?"
> 
> 
> The way I see it this should be correct:
> MemberBooks->search(
>     {
>         'me.relation' => 'has',
>         'me.member_id' => $self->member_id
>     })->search_related('book')->search_related ('mb',
>               {
>                   'mb.relation' => 'wants',
>                   'mb.member_id' => {'!=', $self->member_id}
>               }
>     )->search_related ('member')->search_related('mb',
>     {
>         'mb.relation' => 'has',
>     },
>     { group_by => [' mb.book_id']}
>         );
> 
> But it results in:
> SELECT mb_2.member_id, mb_2.book_id, mb_2.language, mb_2.shape, 
> mb_2.relation FROM member_books me  JOIN book book ON ( book.book_id = 
> me.book_id ) LEFT JOIN member_books mb ON ( mb.book_id = book.book_id )  
> JOIN member member ON ( member.member_id = mb.member_id ) LEFT JOIN 
> member_books mb_2 ON ( mb_2.member_id = member.member_id ) WHERE ( ( ( 
> mb.relation = ? ) AND ( ( ( mb.member_id != ? AND mb.relation = ? ) AND 
> ( me.member_id = ? AND me.relation = ? ) ) ) ) ) GROUP BY mb.book_id 
> LIMIT 10: `has', `1', `wants', `1', `has'
> 
> Instead i have to change the last part to be:
> ->search_related('mb',
>     {
>         'mb_2.relation' => 'has',
>     },
>     { group_by => ['mb_2.book_id']}
>         );
> 
> 
> So my question is, am I doing something wrong here which makes DBIC 
> interpretate my query wrong, or am I supposed to keep track of the naming?

http://search.cpan.org/~jrobinson/DBIx-Class-0.06003/lib/DBIx/Class/ResultSet.pm#join

"If the same join is supplied twice, it will be aliased to <rel>_2 (and 
similarly for a third time)."

Basically, yes, you're supposed to keep track of it. Having a regular, 
simple rule for how relationships get aliased a second or third time 
means that you can always predict accurately what a given table in the 
query is going to be called, and means DBIC can always predirect it 
accurately as well. It takes a little bit of getting used to but once 
you have you'll find you don't have to think about it any more, and it 
ensures that DBIC can do all the magic it always does under the hood 
without trying to keep track of names its been given (which would be 
complex and potentially extremely fragile).



More information about the Dbix-class mailing list