一对多 Eloquent 关系:查询以根据相关表的列值进行过滤

圣彼得

我有两个看起来像这样的表:

stocks

id | name      | market_cap
1  | Microsoft | 5000
2  | Tesla     | 2000

该表与名为 的表具有一对多关系stock_ratings

id | stock_id | measure | value
12 | 1        | revenue | 30
13 | 1        | dividend| 5
14 | 2        | revenue | 10
15 | 2        | dividend| 0

现在,假设用户想要获取所有带有 的股票market_cap > 3000,跳过前 20 个结果,并获取接下来的 20 个结果。这是有效的:

$query = Stock::where('market_cap', '>', 3000);
$stocks = $query->skip(20)->take(20)->get();

但是,用户还需要能够查询 stock_ratings。因此,假设除了上述条件外,他还想找到所有具有value > 20revenue度量的股票

我试过这个,它不起作用。它返回与没有此附加条件时相同的股票列表。

$query = Stock::where('market_cap', '>', 3000);
$query = $query->with(['ratings' => function ($q) {
    $q->where('stock_ratings.measure', 'revenue');
    $q->where('stock_ratings.value', '>', 0);
}]);
$stocks = $query->skip(20)->take(20)->get();

这将返回所有的股票market_cap > 3000无论value并且measurestock_ratings表中。它返回valuestock_ratingswhere 中为负的股票,measure = revenue并且还返回在 stock_ratings 中没有相关行的行。

我该如何解决?

唐卡纳什

当您在with其中应用约束时,意味着该约束应用于哪些嵌套的相关记录应该预先加载,哪些不应该预先加载。

但是,在您的情况下,您希望根据相关评级中包含的值对股票进行过滤或应用限制。

所以试试这个

$query = Stock::where('market_cap', '>', 3000);

$query = $query->whereHas('ratings', function ($q) {
    $q->where('measure', 'revenue');
    $q->where('value', '>', 0);
})-with('ratings');

$stocks = $query->skip(20)->take(20)->get();

在 Laravel 文档中阅读更多内容:https ://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章