laravel - 返回分组结果数组
问题描述
注意:我使用的是 Laravel 5.3。
我有一张桌子,comments
看起来像这样:
+====+=========+
| id | message |
+====+=========+
| 1 | Hi |
| 2 | World |
+====+=========+
我有第二张表,comment_stats
它跟踪每条评论的总票数,如下所示:
+====+============+=======+
| id | comment_id | votes |
+====+============+=======+
| 1 | 1 | 10 |
| 2 | 2 | 0 |
+====+============+=======+
最后,我有第三张表,comment_votes
它跟踪每个用户对每条评论的投票,如下所示:
+====+============+=========+=========+
| id | comment_id | user_id | type |
+====+============+=========+=========+
| 1 | 1 | 10 | 0 |
| 2 | 1 | 9 | 0 |
| 3 | 1 | 8 | 1 |
| 4 | 1 | 7 | 2 |
| 5 | 1 | 6 | 1 |
| 6 | 1 | 5 | 5 |
| 7 | 1 | 4 | 3 |
| 8 | 1 | 3 | 3 |
| 9 | 1 | 2 | 1 |
| 10 | 1 | 1 | 0 |
+====+============+=========+=========+
如您所见,每条评论都可以由其他用户投票 ( comment_votes
),并且总投票数记录在 中comment_stats
。每张选票都有一个type
。总共有 6 个可能type
的 s (0-5)。
我现在的Comment.php
班级看起来像:
class Comment extends Model
{
protected $with = [
'votes', 'stats'
];
public function votes()
{
return $this->hasMany('App\Vote');
}
public function stats()
{
return $this->hasOne('App\Stat');
}
}
我的Stat.php
课看起来像:
class Stat extends Model
{
protected $with = [
'topTypes'
];
public function comment()
{
return $this->belongsTo('App\Comment');
}
public function topTypes()
{
// Need to return an array of the top 3 types here
}
}
我的Vote.php
课看起来像:
class Vote extends Model
{
public function comment()
{
return $this->belongsTo('App\Comment');
}
}
我想检索type
每条评论的前 3 票。所以对于comment_id = 1
,输出将是[0, 1, 3]
(作为一个数组),按这个顺序。0 出现 3 次,1 出现 3 次,3 出现两次。如果有平局,它应该得到较低的整数type
。
我试图让 JSON 最终看起来像这样,因此它top_types
是以下内容的一部分stats
:
{
"id": 1,
"message": "Hi",
"stats": {
"id": 1,
"comment_id": 1,
"votes": 10,
"top_types": [0, 1, 3]
}
}
我怎么能做到这一点?所有这些关系都让我发疯。
解决方案
获得结果很简单。
$result = app(Comment::class)->with('stats.topTypes')->find(1);
接下来,由于您只需要前 3 种类型而不是全部类型,请过滤我们的急切加载查询。
$result = app(Comment::class)->with('stats.topTypes', function (Eloquent\Builder $query) {
$query->limit(3);
})->find(1);
请参阅:约束急切负载
如果这将成为该模型的常见用途,您可能会考虑将该行为移至Query Scope。请注意不要在任何模型类中加载过多的业务逻辑。这可能很诱人,但有点反模式,因为这并不是 MVC 模型层的真正用途。
另一种选择是在方法中将您的限制应用于实际的关系定义Stat::topTypes()
。同样,只有在您确定该关系的所有用例都只需要 3 个结果时才这样做。您也可以在orderByDesc('createdAt')
那里放置一个,这可能在调用案例中更有用。
最后,由于您不想要完整的 Type 模型结果,而只是一个 ID 数组,请记住嵌套结果将采用 Eloquent\Collection 对象的形式,它是 Suppot\Collection 的子对象,可以访问所有相同的钟声和口哨声:
$result->stats->topTypes->transform(function (Type $type) {
return $type->getKey();
});
请参阅:集合(转换)
推荐阅读
- python - 如何在执行 OpenCV 图像减法时去除背景噪声?
- android - 自定义键盘 - 错误的数字输入
- powershell - 空(null)PowerShell 变量
- flex-lexer - 如何在 C++ 中使用 yyextra?
- struct - 为什么 Rust 没有结构的生命周期省略规则?
- python - 使用python根据变量正确打印字符
- ionic3 - 使用 put 方法的 Ionic 3 图像上传
- android - GPS 在我的 android 应用程序中不起作用,但它在 Google 地图中起作用
- c# - 在我隐藏键盘之前,在 SearchView 上键入时 ListView 不会更新
- android - 精明边缘检测器后的opencv洪水填充