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-&gt;user-&gt;__get()。因此,要使其完全可靠,您需要检查hasGetMutator()relations 等。详情请查看Models __get__set

【讨论】:

以上是关于Laravel:每当我返回一个模型时,总是返回一个与它的关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel删除模型自定义返回

每当我发送包含 Bearer 令牌的请求时,ASP.Net Core API 总是返回 401 未授权

Laravel 与 uuid 的多对多关系返回总是空的

Laravel 中的密码验证总是返回失败(Hash::check)

Laravel PHPUnit 返回 404

auth laravel 总是返回 false