我有一种复杂的数据模型,我试图用Laravel 5 / Eloquent编写我的查询,而不只是简单的ol' SQL。我的SQL下面有效,但是我喝了kool-aid,我想让它正常工作'正确'方式。
Actors和Poses之间有many to many relationship,Poses和Categories之间有many to many polymorphic relationship。
我想做的是通过姿势获取与演员相关联的所有不同类别的列表。
SELECT DISTINCT
categories.name,
categories.parent_id
FROM
actor_pose
JOIN
poses ON poses.id = actor_pose.pose_id
JOIN
categorizables ON categorizables.categorizable_id = poses.id
JOIN
categories ON categories.id = categorizables.category_id
WHERE
actor_pose.actor_id = 1 AND
categorizables.categorizable_type = "App\\Pose"
ORDER BY
parent_id
演员 ID 名称
构成 ID 名称
类别 ID 名称 PARENT_ID
categorizables CATEGORY_ID categorizable_id categorizable_type
CategorizableTrait.php
<?php namespace App;
trait CategorizableTrait {
public function categories()
{
return $this->morphToMany('App\Category', 'categorizable');
}
}
Pose.php
<?php namespace App;
class Pose extends Model
{
use CategorizableTrait;
public function actors()
{
return $this->belongsToMany('App\Actor')->withTimestamps();
}
}
Actor.php
<?php namespace App;
class Actor extends Model
{
public function poses()
{
return $this->belongsToMany('App\Pose')->withTimestamps();
}
答案 0 :(得分:1)
Collection
类有一些非常好的方法来处理这类事情。只需使用with()
来建立你的关系并获得你想要的演员。循环关系并添加到集合中。
$categories = new \Illuminate\Database\Eloquent\Collection();
$actor = App\Actor::with('poses.categories')->find($actor_id);
foreach($actor->poses as $pose) {
foreach($pose->categories as $catgegory) {
$categories->add($catgegory);
}
}
$categories = $categories->unique();
如果您希望页面上的所有演员都有自己独特的类别,那么它只是嵌套在另一个循环中的所有内容。
$actors = App\Actor::with('poses.categories')->get();
$actor_categories = [];
foreach($actors as $actor) {
$actor_categories[$actor->id] = new \Illuminate\Database\Eloquent\Collection();
foreach($actor->poses as $pose) {
foreach($pose->categories as $category) {
$actor_categories[$actor->id]->add($category);
}
}
$actor_categories[$actor->id] = $actor_categories[$actor->id]->unique();
}
您最终会得到一个数组,您可以将该数组传递给视图,其中键是actor的id,值是唯一类别的集合。例如,如果你想循环播放演员1的类别,你可以做类似......
foreach($actor_categories[1] as $category) {
echo $category->name;
}
答案 1 :(得分:1)
来自SoftOnSofa的Jarek Tkaczyk链接有一个我最终使用的干净解决方案。
我将此方法添加到我的Actor.php文件中。
<强> Actor.php 强>
public function getCategoriesAttribute()
{
$categories = new Collection;
$this->load(['poses.categories' => function ($q) use ( &$categories ) {
$categories = $q->get()->unique();
}]);
return $categories->sortBy('order')->sortBy('parent_id');
}
控制器没有做任何特别的事情。在刀片中,您可以按如下方式访问它。
<强> index.blade.php 强>
@foreach($actor->categories as $key => $category)
{{ $category->name }}
@endforeach