[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