能否将Laravel的HasOne关系也用作HasOneOrZero关系?
示例: 在文档中,描述了用户和电话之间的HasOne关系。如果每个用户只有0或1个电话,是否可以使用此关系?还是我需要拥有一个OneToMany关系才能允许0?
我不确定如果将HasOne关系用作HasOneOrZero关系是否会导致任何问题。
是的,你可以将 HasOne
视为 HasOneOrZero
关系来使用。
HasOne
关系可以为 null
,在数据库中不需要有关联行。只需要在获取时检查即可。
此外,你可能需要并且会喜欢新的 5.5 版本中的 optional
函数。
其工作原理如下:
optional($user->phone)->number;
如果你有电话号码,它会返回一个数字,但如果没有,则会返回null
而不是尝试获取非对象属性
。除了astratyandmitry之外,我还想补充一下我发现的内容。在我自己思考HasOne
和HasMany
之间实际上有什么区别后,我得出了以下结论。
首先,它们都具有相同的表结构。
用户表:
id | name
1 | Alice
2 | Bob
id | user_id | phone
1 | 1 | 123
2 | 2 | 321
在Model
类中,hasMany和hasOne方法是一样的,唯一不同的是它们返回的对象:
public function hasOne($related, $foreignKey = null, $localKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related;
$localKey = $localKey ?: $this->getKeyName();
return new HasOne($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
}
并且
public function hasMany($related, $foreignKey = null, $localKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related;
$localKey = $localKey ?: $this->getKeyName();
return new HasMany($instance->newQuery(), $this, $instance->getTable().'.'.$foreignKey, $localKey);
}
HasOne
和 class HasMany
)仅在3个函数中有所不同:
getResults()
方法是通过神奇的 __get()
方法调用的,每当关系在没有括号的情况下被调用时(参见 此处),就像这样。$user->phone
这是类hasOne
的getResults()
方法:
public function getResults()
{
return $this->query->first() ?: $this->getDefaultFor($this->parent);
}
hasOne
public function phone()
{
return $this->hasOne('App\Phone');
}
hasMany
类中的 getResults()
方法如下:public function getResults()
{
return $this->query->get();
}
因此,输出为空集合:
如果关系被声明为hasMany
public function phone()
{
return $this->hasMany('App\Phone');
}
HasOne
关系将返回null
,可以按照astratyandmitry在他的帖子中描述的方式处理它。initRelation()
方法或match()
方法何时被调用。