我有一个国家/地区表和一个数据透视表Country_language,其中列出了所有国家/地区的翻译版本。
表结构如下:
Languages
--------------
ID
Locale
Records :
1 - EN
2 - FR
Countries
------------
ID
code
Records:
1 - BE
2 - US
Country_language
-----------------------
ID
country_id
language_id
name
Records :
1 - 1 - 1 - Belgium
2 - 1 - 2 - Belgique
3 - 2 - 1 - United States
4 - 2 - 3 - Les États-Unis
在我的国家/地区模型中,我与语言数据透视表有如下关系:
public function translation()
{
return $this->belongsToMany('Language', 'country_language', 'country_id','language_id')->withPivot('name');
}
现在我想得到一个给定语言的所有国家的列表,这应该按名称DESC进行排序。
我使用以下代码执行此操作:
$countries = Country::with(array('translation' => function($query) {
$query->where('language_id', '=', 1); // fetch countries in English
$query->orderBy('name', 'desc');
}))->get();
如果我打印$ countries但是我得到以下列表,其顺序不正确。我希望它首先给“美国”,然后给“比利时”。
[
{
"id": 1,
"code": "BE",
"translation":
[{
"id": 1,
"locale": "EN",
"pivot":
{
"country_id": 1,
"language_id": 1,
"name": "Belgium"
}
}]
},
{
"id": 2,
"code": "US",
"translation":
[{
"id": 2,
"locale": "EN",
"pivot":
{
"country_id": 2,
"language_id": 1,
"name": "United States"
}
}]
}
]
如果我检查正在运行的查询,它看起来如下:
select `languages`.*, `country_language`.`country_id` as `pivot_country_id`, `country_language`.`language_id` as `pivot_language_id`,
`country_language`.`name` as `pivot_name` from `languages`
inner join `country_language` on `languages`.`id` = `country_language`.`language_id`
where `country_language`.`country_id` in (?, ?) and `language_id` = ? order by `name` desc
哪个是正确的,如果我在MySQL中运行,我会按名称顺序降序获取国家/地区列表。
我在这里做错了什么,或者这可能是Laravel的一个问题? 感谢您抽出宝贵时间回答。
编辑: 基本上我只想在Eloquent中进行以下查询..看起来很简单,但显然很难(如果可能的话)在Eloquent中完成:
select country_language.*, languages.*
from country_language
join countries on countries.id = country_language.country_id
join languages on languages.id = country_language.language_id
where country_language.language_id = 1
order by country_language.name desc
答案 0 :(得分:0)
您正在使用急切的加载限制。 这不会影响外部查询的结果 - 它只限制和排序相关记录。如果你愿意,例如检索$ countries-> first() - >翻译 - >那些是按名称排序的。
在您的情况下,即使country_language表中没有记录,您也会收到所有国家/地区。因为您的限制仅适用于相关记录。
如果您只想在country_language表中拥有相关记录的国家/地区,则应使用whereHas。这可能会导致类似:
$countries = Country::with(array('translation' => function($query) {
$query->where('language_id', '=', 1); // fetch only country_language records with language_id = 1
}))->whereHas('translation', function($query) {
$query->where('language_id', '=', 1); // fetch countries in English
$query->orderBy('name', 'desc');
->get();
请检查这是否会以正确的方式订购您的结果。我可以想象orderBy必须链接在原始国家集合上,因此在内部函数中不。
那应该是这样的:
$countries = Country::with(array('translation' => function($query) {
$query->where('language_id', '=', 1); // fetch only country_language records with language_id = 1
}))->whereHas('translation', function($query) {
$query->where('language_id', '=', 1); // fetch countries in English
->orderBy('name', 'desc');
->get();
在这种情况下,我不确定您是否可以在name
列上订购。也许它不可访问,那么你可能需要使用join语句。