使用关系名称“用户”时,BelongsTo 关系返回 null
Posted
技术标签:
【中文标题】使用关系名称“用户”时,BelongsTo 关系返回 null【英文标题】:BelongsTo relationship returns null when using relation name "user" 【发布时间】:2018-04-23 14:40:25 【问题描述】:在 Laravel 5.5 中创建简单的一对一关系时,每当我使用方法/关系名称 user
时,$person->user
都会返回一个 null
值。如果我将名称更改为foo
、User
或login
,代码似乎可以正常工作。这是我遇到同样问题的第二个项目。谁能看到我做错了什么?
个人模型:
public function user()
return $this->belongsTo(User::class, 'user_id', 'id');
public function foo()
return $this->belongsTo(User::class, 'user_id', 'id');
public function getUser()
if ($this->user_id)
return User::find($this->user_id);
else
return null;
在个人测试中:
$user = factory(User::class)->create();
$person = factory(Person::class)->create(['user_id' => $user->id]);
// This works
$this->assertTrue( $person->getUser()->is($user) );
// This works
$this->assertTrue( !is_null($person->foo) );
if ( $person->foo )
$this->assertTrue( $person->foo->is($user) );
// This fails
$this->assertTrue( !is_null($person->user) );
if ( $person->user )
$this->assertTrue( $person->user->is($user) );
根据要求,这里是与 Person 相关的所有代码, 整个 App\Models\Person.php:
use App\Models\User;
use App\Models\Asset;
use App\Traits\HasGuid;
use App\Traits\HasNotes;
use App\Traits\HasModifiedBy;
use App\Traits\HasAttachments;
use App\Traits\HasRelationships;
use App\Transformers\PersonTransformer;
use App\Models\Abstracts\HasTypeModelAbstract;
use App\Models\Interfaces\HasTypeModelInterface;
class Person extends HasTypeModelAbstract implements HasTypeModelInterface
use HasModifiedBy,
HasNotes,
HasAttachments,
HasRelationships;
protected $fillable = [
'person_type_id',
'email',
'fname',
'lname',
'user_id',
'modified_by_user_id',
'audited_at',
'custom_attributes'
];
protected $casts = [
'custom_attributes' => 'json',
'user_id' => 'integer',
'modified_by_user_id' => 'integer',
'person_type_id' => 'integer'
];
protected $dates = [
'audited_at'
];
public static $transformer = PersonTransformer::class;
public function user()
return $this->belongsTo(User::class, 'user_id', 'id');
public function type()
return $this->belongsTo(PersonType::class, 'person_type_id');
public function assets()
return $this->hasMany(Asset::class, 'person_id');
性状:
trait HasNotes
protected static function bootHasNotes()
static::deleting(function ($instance)
$instance->notes->each(function ($note)
$note->delete();
);
);
public function notes()
return $this->morphMany(Note::class, 'notable');
trait HasModifiedBy
protected static function bootHasModifiedBy()
static::saving(function ($instance)
$instance->modified_by_user_id = Auth::id();
);
public function modifiedBy()
return $this->belongsTo(User::class, 'modified_by_user_id');
trait HasAttachments
protected static function bootHasAttachments()
static::deleting(function ($instance)
$instance->attachments->each(function ($attachment)
$attachment->delete();
);
);
public function attachments()
return $this->morphMany(Attachment::class, 'attachable');
trait HasRelationships
protected static function bootHasRelationships()
static::deleting(function ($instance)
Relation::forObject( $instance )->delete();
);
public function related() ...[long polymorphic relationship here]...
/App/Models/Abstracts/HasTypeModelAbstract
use Illuminate\Database\Eloquent\Model;
// This thing just appends some custom attributes dynamically in the JSON and array forms. And no, 'user' is not a custom attribute key.
abstract class HasTypeModelAbstract extends Model
public function newFromBuilder($attributes = array(), $connection = NULL)
$instance = parent::newFromBuilder($attributes);
$instance->appendCustomAttributes();
return $instance;
protected function appendCustomAttributes()
$this->append( $this->getCustomAttributesFromType() );
public function getCustomAttributesFromType()
if ($this->type)
return $this->type->custom_attributes ?
array_keys((array) $this->type->custom_attributes) : [];
else
return [];
protected function setCustomAttributesFromType($attributes = array())
if ($this->type)
$custom_attribute_keys = $this->getCustomAttributesFromType();
$custom_attributes = (array) $this->custom_attributes ?: [];
foreach ($custom_attribute_keys as $key)
$attributes[$key] = array_get($custom_attributes, $key);
return $attributes;
protected function addMutatedAttributesToArray(array $attributes, array $mutatedAttributes)
$this->appendCustomAttributes($this, $attributes);
$attributes = $this->setCustomAttributesFromType($attributes);
return parent::addMutatedAttributesToArray($attributes, $mutatedAttributes);
protected function mutateAttribute($key, $value)
$keys = $this->getCustomAttributesFromType();
if ( in_array($key, $keys) )
return $this->getCustomAttributeValue( $key, $value );
return parent::mutateAttribute($key, $value);
protected function getCustomAttributeValue($key, $value)
$custom_attributes = (array) $this->custom_attributes ?: [];
return array_get($custom_attributes, $key, $value);
【问题讨论】:
您的 Person 模型或方法getUserAttribute
中是否有 user
列?
不。我还检查了所有遗传特征等。
您能否在整个文件中包含您使用的任何自定义特征?
完成。请注意,“用户”不是“HasTypeModelAbstract”类中的自定义属性键
【参考方案1】:
说实话 - 快速查看代码我没有发现任何问题,但这并不意味着一切都很好。
如果我是你,我会尝试将 Person 模型限制为:
class Person extends \Illuminate\Database\Eloquent\Model
protected $fillable = [
'person_type_id',
'email',
'fname',
'lname',
'user_id',
'modified_by_user_id',
'audited_at',
'custom_attributes'
];
protected $casts = [
'custom_attributes' => 'json',
'user_id' => 'integer',
'modified_by_user_id' => 'integer',
'person_type_id' => 'integer'
];
protected $dates = [
'audited_at'
];
public static $transformer = PersonTransformer::class;
public function user()
return $this->belongsTo(User::class, 'user_id', 'id');
public function type()
return $this->belongsTo(PersonType::class, 'person_type_id');
public function assets()
return $this->hasMany(Asset::class, 'person_id');
现在我将验证一切是否正常。如果没问题,现在您可以进一步调查,添加一个特征并验证,添加第二个特征并验证,最后从同一个类扩展。
某处肯定有错误,但查看这段代码很难找到任何东西
【讨论】:
【参考方案2】:user 是 eloquent 中的保留名称。
尝试用户而不是用户
public function User()
return $this->belongsTo(User::class, 'user_id', 'id');
【讨论】:
我知道我可以更改方法名称。我在上面提到它适用于“用户”。您在哪里发现“用户”是 Eloquent 中的保留名称?它不是模型上的属性。我无法找到任何关于它的文档。我很想看一份清单。以上是关于使用关系名称“用户”时,BelongsTo 关系返回 null的主要内容,如果未能解决你的问题,请参考以下文章
Laravel:更改其函数名称时,belongsTo 不起作用
Laravel:belongsTo()关系假设一对多关系而不是一对一
CakePHP hasOne belongsTo 关系,编辑/添加相同动作