我有两张桌子:
User | Doctor
---------- | ----------
id | id
email | user_id
name | signature
last_name | photo
password | description
date_birth |
每个Doctor
都与User
相关,但每个User
可能与Doctor
无关。我是这样做的,因为我不想使用单表继承并最终得到一堆NULL
字段。
有没有办法制作,像这样?
// Instead of
$doctor = Doctor::with('User')->find(1);
$doctor->user->name;
// This
$doctor = Doctor::find(1);
$doctor->name;
P.S:不知道在标题中放什么,我应该把它放在哪里,以便它与问题更相关?
答案 0 :(得分:16)
您可以使用模型上的$with
属性指定默认的预先加载的关系。
class Doctor extends Eloquent {
protected $with = ['user'];
// ...
}
(该物业可能需要公开,我会忘记。如果确实如此,Laravel会对你大吼大叫。)
您仍然需要使用$doctor->user->name
,但关系将自动加载,而无需您明确调用它。如果确实想要使用$doctor->name
语法,则可以为这些列名创建Accessors,然后获取并传递相应的用户关系列。
答案 1 :(得分:11)
我最终使用Accessors
和$appends
并按预期工作。它甚至出现在文档Appends + Accessors(最后)中。感谢Cyrode,他向我展示了Accessors(不知道他们已经出现了)。
我无法使用$appends
数组,但如果您使用JSON返回模型,则需要它。
正如Jarek Tkaczyk deczo 建议的那样,在使用此方法时应使用with
属性,否则每当您加载多个Doctor
模型并调用任何内容时{{1}相关的,你最终得到一个数据库查询(每个User
实例) - > n + 1期
博士班最终看起来像这样:
Doctor
我必须将<?php
class Doctor extends Eloquent {
protected $table = 'doctors';
protected $with = ['user'];
protected $appends = ['first_name','last_name','email','date_of_birth'];
protected $hidden = ['signature','user'];
public function user(){
return $this->belongsTo('User');
}
public function getFirstNameAttribute() {
return $this->user->first_name;
}
public function getLastNameAttribute() {
return $this->user->last_name;
}
public function getEmailAttribute() {
return $this->user->email;
}
}
放在user
数组中,否则每当我退出$hidden
时它都会出现(除了我只需要Doctor
的某些内容,而不是所有内容)
答案 2 :(得分:0)
是的,有办法。这是好的设计吗?也许,也许不是。你的简短描述很难说。
// Doctor model
public function __get($key)
{
// check deafult behaviour
if (is_null($value = parent::__get($key))) return $value;
// if null, let's try related user
return $this->user->__get($key);
}
public function __set($key, $value)
{
$user = $this->user;
// first try user
if (array_key_exists($key, $user->getAttributes()) || $user->hasSetMutator($key))
{
return $user->__set($key, $value);
}
// then default
parent::__set($key, $value);
}
这样你可以这样做:
$doctor->name; // returns $doctor->user->name; unless you have accessors for name
$doctor->name = 'Some Name';
// then
$doctor->user->name; // 'Some Name';
// so finally push instead of save, in order to save related user too
$doctor->push();
请注意,为简洁起见,这是一个非常简单的例子。 Doctor
模型的现有属性有可能是null
,因此不应该调用$this->user->__get()
。因此,为了使其完全可靠,您需要检查hasGetMutator()
,relations
等。查看Model
s __get
和__set
了解详情。