我得到了一個解決方案。
這不是直截了當,但它比虛擬視圖更好。
http://search.cpan.org/dist/DBIx-Class/lib/DBIx/Class/Relationship/Base.pm#condition
上面介紹瞭如何使用JOIN子句條件。 但是,我的情況在這些情況下需要一個變量,這在模型中默認情況下不可用。因此,繞過一些模型概念並將變量引入它,我們有以下幾點。
在模型文件
our $USER_ID;
__PACKAGE__->has_many(
pindols => "My::MyDB::Result::Read",
sub {
my $args = shift;
die "no user_id specified!" unless $USER_ID;
return ({
"$args->{self_alias}.id" => { -ident => "$args->{foreign_alias}.article_id" },
"$args->{foreign_alias}.user_id" => { -ident => $USER_ID },
});
}
);
在控制器
$My::MyDB::Result::Article::USER_ID = $c->user->id;
$articles = $channel->search(
{ "pindols.user_id" => undef } ,
{
page => int($page),
rows => 20,
order_by => 'last_update DESC',
prefetch => "pindols"
}
);
將取以下SQL所有未讀文章和產量。
SELECT me.id, me.url, me.title, me.content, me.last_update, me.author, me.thumbnail, pindols.article_id, pindols.user_id FROM (SELECT me.id, me.url, me.title, me.content, me.last_update, me.author, me.thumbnail FROM articles me LEFT JOIN reads pindols ON (me.id = pindols.article_id AND pindols.user_id = 9) WHERE (pindols.user_id IS NULL) GROUP BY me.id, me.url, me.title, me.content, me.last_update, me.author, me.thumbnail ORDER BY last_update DESC LIMIT ?) me LEFT JOIN reads pindols ON (me.id = pindols.article_id AND pindols.user_id = 9) WHERE (pindols.user_id IS NULL) ORDER BY last_update DESC: '20'
當然,您可以跳過分頁,但是我已將它放在代碼中,因此我將它包含在此處。
特別感謝deg來自irc.perl.org上的#dbix-class和https://blog.afoolishmanifesto.com/posts/dbix-class-parameterized-relationships/。
感謝, 坎託
您是否嘗試過將其添加爲「標準」 where子句? – 2014-11-14 16:42:18
是的。 「標準」where子句將只過濾那些由用戶讀取的文章(存在於讀取表中)。它不會顯示相應的讀取表項爲NULL的文章。 使用AND和LEFT JOIN會給我所有的文章。如果文章被讀取,User_id字段將被設置,如果不是,則它將是NULL。 – canto 2014-11-14 18:24:02
如果要使用'reads.user_id = NULL'獲取文章,則不能在查詢中使用'AND reads.user_id = 9'條件。 – krokodilko 2014-11-14 18:38:44