好吧,你试图让一个用户,但与他们的球员(其中用户bTM球员)已经填充和按位置(其中枢轴bT位置)排序。
在这种情况下,您将无法不经修改就使用Laravel的内置关系方法,因为Laravel并非专门用于处理其他关系数据透视表上的关系。幸运的是,ORM具有足够的灵活性,可以让您通过“手动”连接完成所需的任务。
那么直接回答你的问题,这里的代码,你需要的那种(你非常接近!):
$user = User::with(['players' => function ($q) {
$q->join('position', 'league_player_user.position_id', '=', 'position.id')
->orderBy('position.sort_id', 'asc');
}])->where('id', Auth::user()->id)->first();
然而,在我看来,这不是伟大的代码有以下几个原因:
- 你手工获得授权的用户(当
Auth::user()
是所以方便)
- 你实际上是不得不采取的具体实现逻辑从日(事实上,数据透视表被称为
league_player_user
,并把它...以及无论这是哪里(您的控制器?)
- 这只会影响这一个单一的查询 - 如果你碰巧得到
User
某种其他方式(例如Auth::user()
或User::find(1)
或其他),你不会有玩家正确
有序因此,我可能会建议,让你的查询更加简单的目的,你不要急于负载的球员。因此,所有你需要做的前期是:
$user = Auth::user();
现在,(在你的User
类球员()方法)的关系,你做的特殊订货工作:
public function players()
{
return $this->belongsToMany('App\Models\Player', 'league_player_user')
->withPivot('position_id')
->join('position', 'league_player_user.position_id', '=', 'position.id')
->orderBy('position.sort_id');
}
这样,任何时候你打电话$user->players
,你会得到他们正确的顺序。
我必须补充一点,这样做可能不会让你急于加载玩家,因为Laravel急于加载(即在ORM链中使用->with()
),这是由于Laravel执行急切的加载查询的方式 - 一个用于主要查询(即用户)和一个关系(即玩家),但它执行此查询以获取所有结果,因此可能无法与特殊订购系统配合使用。你将不得不看看你是否真的在意急于加载玩家。在上面的例子中(你得到的是单个授权用户),我认为急切的加载并不重要。
编辑补充关于预先加载澄清:
我的背后暗示预先加载可能不工作的理由是,在Laravel渴望加载还挺喜欢这样做:说你有类别和产品:Category
HM Product
,Product
bT Category
。要获得您使用的类别$category = Category::find(1)
,并且Laravel将其转换为查询,如下所示:SELECT * FROM `categories` WHERE `id` = '1'
。如果您随后致电$category->products
,Laravel将发出SELECT * FROM `products` WHERE `category_id` = '1'
。这很明智。但是,如果你有下面的代码它会更糟糕:
<?php $categories = Category::all(); ?>
<ul>
@foreach ($categories as $category)
<li>Category {{{ $category->name }}} contains {{{ $category->products->count() }}} products.</li>
@endforeach
</ul>
在这种情况下,你有以下疑问:
SELECT * FROM `categories`;
SELECT * FROM `products` WHERE `category_id` = '1';
SELECT * FROM `products` WHERE `category_id` = '2';
SELECT * FROM `products` WHERE `category_id` = '3';
... as many categories as you had
但是,如果你要改变的是第一线,这:
<?php $categories = Category::with('products')->get(); ?>
现在你只有两个疑问:
SELECT * FROM `categories`;
SELECT * FROM `products` WHERE `category_id` IN ('1', '2', '3', ...);
然后,Laravel在调用第二个查询之后,将根据它知道的类别ID为您创建各种集合。
但是,这是简单化的关系案例。在你的情况下,products()
方法不仅仅是return $this->hasMany('Product');
,但它包括一个数据透视表和一个手动连接等等,而且第二个查询,即急切加载的查询,可能无法应付并且做到这一点正确排序。
正如我所说,我不确定这是如何工作的,这对我来说只是一个红旗。通过一切手段给它一个去看看你得到了什么 - 你可能会发现它适合你。
'User'模型中的'belongsToMany'会自动加入数据透视表(和远表('players')),但不会加入'position'表(即使你说你想要position_id因此,你需要确保你自己添加额外的连接,我认为你可以通过'User :: with('players','players.position')'做到这一点(尽管'position_id'是一个虚拟的你可能无法做到这一点,你必须使用代码),重点在于'position'不会自动加入,所以你不能在它上面订购。 – alexrussell
感谢@alexrussell。我已经看过这个,是的 - 也渴望加载嵌套关系。然后我可以在players.position中使用orderBy()查询,尽管它没有错误,但它并没有正确地对结果进行排序。 – Alex
而不是使用' - > first()'use' - > toSql )'返回它正在生成的SQL - 这将帮助您准确调试ORM将要发布的内容。 – alexrussell