[Dbix-class] Adding dynamic join conditions
Renaud Drousies
renaud at linuxaddicts.com
Tue Sep 5 17:55:22 CEST 2006
Hello,
I am sorry if this is a FAQ, I couldn't find help in the documentation nor
the cookbook. I am trying to find information about how to add "dynamic"
conditions in the join conditions, here is my example:
Restaurants >---hasmany--- Categories
|
hasmany
|
/|\
Categories_trans
This means a restaurant belongs to 1 category (fast-food, greek, etc...)
and that category can be translated in multiple languages,
Categories_trans contains 3 fields: category, which links to Categories,
lang, which is a language code, and label, which is the translation in
that language.
Here are the relationships I have defined:
Categories:
__PACKAGE__->has_many(restaurants => 'DB::Resto::Restaurants' => 'category');
__PACKAGE__->has_many(trans => 'DB::Resto::CategoriesTrans' => 'category',
{join_type => 'left'});
Restaurants:
__PACKAGE__->belongs_to(category => 'DB::Resto::Categories');
CategoriesTrans:
__PACKAGE__->belongs_to(categories => 'DB::Resto::Categories' => 'category');
My problem is that I would like to add a dynamic left join condition
between Categories and CategoriesTrans based on the language, right now
what I have is:
$c->stash->{by_category} = [$c->model('Resto::Restaurants')->search(
{
'city.province' => $c->stash->{province},
'trans.lang' => $c->stash->{language}
},
{
join => ['city', { 'category' => 'trans' }],
select => [ 'category.id', 'trans.label', { count =>
'me.id' } ],
as => [ 'id', 'name', 'count' ],
group_by => [qw/ category.id trans.label /] ,
order_by => [qw/ trans.label /]
}
) ];
but this generates a query as:
SELECT category.id, trans.label, COUNT( me.id )
FROM Restaurants me
JOIN Cities city ON ( city.id = me.city )
JOIN Categories category ON ( category.id = me.category )
LEFT JOIN Categories_trans trans ON ( trans.category = category.id )
WHERE ( city.province = 'qc' AND trans.lang = 'fr' )
GROUP BY category.id, trans.label
ORDER BY trans.label
As you see, the condition is "global" (I am not sure what the term is). I
would like to list all Categories and the count of restaurants that are in
them, but the problem with that condition is that it will not list the
categories that have no label in the current language, what Id like is to
have a row with a NULL label when this happens, so a query like :
SELECT category.id, trans.label, COUNT( me.id )
FROM Restaurants me
JOIN Cities city ON ( city.id = me.city )
JOIN Categories category ON ( category.id = me.category )
LEFT JOIN Categories_trans trans ON ( trans.category = category.id AND
trans.lang='fr')
WHERE ( city.province = 'qc' )
GROUP BY category.id, trans.label
ORDER BY trans.label
Is this possible with DBIx::Class?
Thanks!
Regards,
Renaud
More information about the Dbix-class
mailing list