【发布时间】: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”类中的自定义属性键
标签: laravel laravel-5 eloquent phpunit laravel-5.5