Laravel:每当我返回一个模型时,总是返回一个与它的关系
Posted
技术标签:
【中文标题】Laravel:每当我返回一个模型时,总是返回一个与它的关系【英文标题】:Laravel: Whenever I return a model always return a relationship with it 【发布时间】:2014-10-29 17:08:57 【问题描述】:我有 2 张桌子:
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:不知道在标题中应该放什么,我应该放什么来代替它与问题更相关?
【问题讨论】:
如果医生没有用户,您是否仍希望在结果中看到该医生? 医生总是与用户相关(至少在这种情况下)。请阅读对Matthew Rath
所做答案的评论。
【参考方案1】:
您可以使用模型上的$with
属性指定默认的预先加载的关系。
class Doctor extends Eloquent
protected $with = ['user'];
// ...
(该属性可能需要公开,我忘记了。如果这样做,Laravel 会对你大喊大叫。)
您仍然需要使用$doctor->user->name
,但关系将自动加载,无需您显式调用它。如果您真的想使用$doctor->name
语法,您可以为这些列名创建Accessors,然后获取并传递适当的用户关系列。
【讨论】:
我最终使用了访问器和 $appends,它按预期工作。它甚至出现在文档Appends + Accessors (at the end)。 不知道这只是打勾,它只是解决了我的问题【参考方案2】:我最终使用了Accessors
和$appends
,它按预期工作。它甚至出现在文档 Appends + Accessors 中(最后)。感谢 Cyrode,他向我展示了 Accessor(不知道它们存在)。
我不能使用 $appends
数组,但如果您以 JSON 格式返回模型,则需要它。
正如 Jarek Tkaczyk deczo 所建议的,当你采用这种方法时,你应该使用 with
属性,否则当你加载多个 Doctor
模型并调用任何与 User
相关的东西时,你最终会使用数据库查询(每个 Doctor
实例)-> 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
时它就会出现(此外我只需要User
的一些东西,而不是全部)
【讨论】:
当你使用这种方法时,你应该使用with
属性,否则当你加载多个Doctor
模型并调用任何与User
相关的东西时,你最终会得到一个数据库查询(每个医生实例)-> n+1 期
谢谢 Jarek,好建议。将相应地更新答案。【参考方案3】:
是的,有办法。是好的设计吗?也许,也许不是。从你的简短描述很难说。
// 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
。
【讨论】:
以上是关于Laravel:每当我返回一个模型时,总是返回一个与它的关系的主要内容,如果未能解决你的问题,请参考以下文章
每当我发送包含 Bearer 令牌的请求时,ASP.Net Core API 总是返回 401 未授权