将 Eloquent HasMany 关系转换为 HasOne?
Convert Eloquent HasMany relationship to a HasOne?
好的,我的模型 A
链接到许多模型 B
,因此模型 A
与模型 B
有 hasMany
关系,并且模型 B
与模型 A
.
有 belongsTo
关系
但是,在所有这些 B
中,有一个特别的,例如价值更高的那个,我希望模型 A
与之建立专门的关系。
我知道我可以在模型 A
中创建第二个关系,重新使用旧关系并添加我想要的所有范围和条件,但由于我是从 hasMany
,无论如何,它总是 return 一组结果。
有没有办法让它 return 成为一个结果而不是一个集合?我知道我可以添加一个 first()
,但这涉及将这个新关系用作一个函数,即始终带有括号,如果可能的话,我仍然希望以 eloquent 的方式使用它。
可以吗?如果是,怎么做?
不是真的没有。您有 2 个模型映射表,其中一些属性如下
+-----+-----+
| A | B |
+-----+-----+
| id | id |
| ... | a_id|
| | ... |
+-----+-----+
当您调用 hasMany
关系时,构建器会执行一个查询。像
SELECT * FROM `B` WHERE `B`.`a_id` = ?
如果为它创建不同的关系,则只会复制查询(如果同时加载这两个关系)。你可以做一个 accessor
,或者只使用 first()
.
编辑访问代码:
# A model
public function getXAttribute()
{
// Query only if necessary
if(!this->relationLoaded('b')) $this->load('b');
// Use Collection methods to filter
return $this->b->firstWhere(...);
}
这个怎么样:
public function Bs()
{
return $this->hasMany(B::class);
}
public function B()
{
$builder = $this->Bs()->latest(); // Add your own conditions etc...
$relation = new HasOne($builder->getQuery(), $this, 'a_id', 'id');
return $relation; // or return $relation->withDefault();
}
更新:
Laravel 8.42 附带了一个新的一对多 关系。您可能想改用它:
public function B(): HasOne
{
return $this->hasOne(B::class)->latestOfMany();
}
好的,我的模型 A
链接到许多模型 B
,因此模型 A
与模型 B
有 hasMany
关系,并且模型 B
与模型 A
.
belongsTo
关系
但是,在所有这些 B
中,有一个特别的,例如价值更高的那个,我希望模型 A
与之建立专门的关系。
我知道我可以在模型 A
中创建第二个关系,重新使用旧关系并添加我想要的所有范围和条件,但由于我是从 hasMany
,无论如何,它总是 return 一组结果。
有没有办法让它 return 成为一个结果而不是一个集合?我知道我可以添加一个 first()
,但这涉及将这个新关系用作一个函数,即始终带有括号,如果可能的话,我仍然希望以 eloquent 的方式使用它。
可以吗?如果是,怎么做?
不是真的没有。您有 2 个模型映射表,其中一些属性如下
+-----+-----+
| A | B |
+-----+-----+
| id | id |
| ... | a_id|
| | ... |
+-----+-----+
当您调用 hasMany
关系时,构建器会执行一个查询。像
SELECT * FROM `B` WHERE `B`.`a_id` = ?
如果为它创建不同的关系,则只会复制查询(如果同时加载这两个关系)。你可以做一个 accessor
,或者只使用 first()
.
编辑访问代码:
# A model
public function getXAttribute()
{
// Query only if necessary
if(!this->relationLoaded('b')) $this->load('b');
// Use Collection methods to filter
return $this->b->firstWhere(...);
}
这个怎么样:
public function Bs()
{
return $this->hasMany(B::class);
}
public function B()
{
$builder = $this->Bs()->latest(); // Add your own conditions etc...
$relation = new HasOne($builder->getQuery(), $this, 'a_id', 'id');
return $relation; // or return $relation->withDefault();
}
更新:
Laravel 8.42 附带了一个新的一对多 关系。您可能想改用它:
public function B(): HasOne
{
return $this->hasOne(B::class)->latestOfMany();
}