[Dbix-class] Chaining resultsets that join to the same table

Byron Young Byron.Young at riverbed.com
Fri May 29 23:25:31 GMT 2009


Peter Rabbitson wrote on 2009-05-29:
> Byron Young wrote:
>> Peter Rabbitson wrote on 2009-05-29:
>>> Peter Rabbitson wrote:
>>>> Byron Young wrote:
>>>>> Hey all,
>>>>> 
>>>>>  Is there a better way to solve this issue so that I can chain
> queries
>>>>> that don't collide even if they join to the same table?
>>>>> 
>>>>> This is definitely not a faq, and concerns one of the hairier
> parts of
>>>> DBIC. Since 0.08103 DBIC can do the counting for you properly, but
>>>> with the caveat that you are accessing internal methods which can
>>>> change without notice:
>>>> 
>>>> my $aliases = $rs->_joinpath_aliases ($rs->_resolved_attrs-
>>>> {from});
>>>> 
>>>> If you Data::Dumper the resulting hashref you will see that the
>>>> answer to your question is then as simple as:
>>>> 
>>>> my $alias = $aliases-
>>>> {map_results_tested_hosts}{tested_host}{hostname};
>>>> 
>>> Sorry, my bad. What I sent will not work correctly if you have
>>> ->search_related calls in your chain. The full code is:
>>> 
>>> my $rattr = $rs->_resolved_attrs_copy;
>>> my $aliases = $rs->_joinpath_aliases ($rattr->{from}, $rattr-
>>>> {seen_join});
>>  Thanks for the help, Peter.  I'll look into upgrading at some point so
>> I can get those features.  I'm still running 0.08010.
>> 
>> I'm curious, though - why can't search() do this internally with
> the search conditions?  If it sees 'table.column' in the condition
> and it knows it's joining to 'table' and that 'table' will have an
> alias 'table_X', couldn't it update the search condition and do
> that work behind the scenes?
>> 
>> If it's something that could be done but nobody has had the time
> or inclination, I'd be happy to offer a patch provided I can get
> some guidance with the DBIC internals.  However, I'm going to guess
> that there are lots of implications to a change like this that I'm
> not aware of, and that it's probably been thought through and
> dumped a few times already.
>> 
> 
> Because how does search() know that you want to search on the
> join you just supplied or on the join that appeared in a
> search() before? Instead of making assumptions, dbic does
> exactly what you told it to.
> 

Good point. 

What about adding a way to specify the alias for the join table in the search() attributes?  Since I have total control over the search condition and can't expect search() to assume it knows what I'm trying to do, I think it would be nice if I could have the same control over the joined table aliases.  Then I could design my resultset methods or auto-generated filter queries so I knew the search condition matched the table alias and wouldn't collide in a chained query.

For example (the syntax is made up, I think that would be the hardest thing about adding a feature like this, and my suggestion may be total crap - maybe somebody has a relationship named '-as'?):

  my $rs = $rs->search({ 'rel1_join_table.column' => 'value' },
                       { join => { 'rel1' => { 'join_table' => { -as => 'rel1_join_table' } } } })
              ->search({ 'rel2_join_table.column' => 'value' },
                       { join => { 'rel2' => { 'join_table' => { -as => 'rel2_join_table' } } } });

Another fine solution (to me, at least) would be a public interface to the join path aliases, like what you provided but without the internal methods.

Again, I'm willing to work on it but I would need some pointing in the right direction.

Byron



More information about the DBIx-Class mailing list