Laravel模型附件,'Call to a member function getAttribute() on null'



我试图配置我的Laravel应用程序存储/检索用户电子邮件从一个单独的,相关的表。我希望Laravel的内置User模型从相关的Person模型检索其电子邮件记录,该模型由User上的person_id字段链接。

我遵循了这个答案中的步骤,这与我的场景非常相似。

然而,我遇到了一个问题:

我创建了一个新用户,检查记录显示一切都已正确设置:Person模型创建了User中未包含的额外信息,User通过名为person的关系正确引用了Person模型。我可以使用新用户登录,这让我认为服务提供商的链接也很正确。

当我发送一个密码重置链接,然而,我得到错误:

AppModelsUser : 65
getEmailAttribute
'Call to a member function getAttribute() on null'

.

public function person()
{
return $this->belongsTo(Person::class);
}
public function getEmailAttribute()
{
// Error occurs here!
return $this->person->getAttribute('email');
}

public function getFirstNameAttribute()
{
return $this->person->getAttribute('firstName');
}

public function getLastNameAttribute()
{
return $this->person->getAttribute('lastName');
}

似乎Password::sendResetLink中的代码认为person的关系是空的。我已经检查了它试图引用的Userid,手动检查显示person是定义的,我甚至可以正常使用访问器,例如User::find({id})->email。我想不出为什么person是null的任何理由,因为它被设置为数据库级别的外键约束…

尝试在我的应用程序中的另一个用户帐户上重置密码-这个是由数据库种子器创建的-它工作得很好…

另外,一个无意义的电子邮件(不存储在DB)产生相同的错误…虽然我已经确认,我第一次遇到这个错误是使用正确的电子邮件,存储在DB…

编辑:

public function retrieveByCredentials(array $credentials)
{
if (
empty($credentials) ||
(count($credentials) === 1 &&
str_contains($this->firstCredentialKey($credentials), 'password'))
) {
return;
}
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->newModelQuery();
foreach ($credentials as $key => $value) {
if (str_contains($key, 'password')) {
continue;
}

if (is_array($value) || $value instanceof Arrayable) {
$query->with([$this->foreign_model => function ($q) use ($key, $value) {
$q->whereIn($key, $value);
}]);
} elseif ($value instanceof Closure) {
$value($query);
} else {
//This is not working
$query->with([$this->foreign_model => function ($q) use ($key, $value) {
$q->where($key, $value);
}]);
}
}
return $query->first();
}

.

'users' => [
'driver' => 'person_user_provider',
'model' => AppModelsUser::class,
'foreign_model' => 'person'
],

在我的经验中,不知何故你的应用程序调用这个逻辑与错误的数据,你不确定是什么原因造成的。有大量的异常服务,可以更深入地了解这是如何发生的,上下文,url调用等等。既然你在这里问这个问题,我猜你想修理它,我们可以帮助解决我描述的第一种情况。

相反,为什么不创建一个防御方法来帮助这种情况,这种情况会不断出现。Laraveloptional()助手,这使得它可以调用null对象而不会导致代码崩溃,变量将以null结束。

return optional($this->person)->getAttribute('email');

PHP 8有一个?->nullsafe操作符,它做同样的事情。我假设PHP 8没有被广泛采用,所以可选将在所有情况下工作。

return $this->person?->getAttribute('email');

最新更新