Laravel:每当我返回模型时,总会返回与之关系

时间:2014-09-04 20:07:52

标签: laravel laravel-4 model eloquent

我有两张桌子:

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:不知道在标题中放什么,我应该把它放在哪里,以便它与问题更相关?

3 个答案:

答案 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了解详情。