首页 > 解决方案 > Laravel:使用 belongsTo() 向我的模型添加意外属性

问题描述

我正在使用 Lumen 编写一个 REST API。我的示例有 2 个模型UserPost. Postmodel 使用该方法belongsTo获取User创建此帖子的模型。我的目标是定义一个访问器,这样我就可以像那样获取帖子的作者用户名Post::find($id)->author。所以根据文档我这样做:

Post.php:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
  protected $table = 'posts';
  protected $appends = ['author'];

  protected $fillable = [
    'title',
    'description'
  ];

  protected $hidden = [
    'user_id',
    'created_at',
    'updated_at'
  ];

  public function user()
  {
    return $this->belongsTo('App\User', 'user_id');
  }

  public function getAuthorAttribute()
  {
    return $this->user->username;
  }
}

现在 getter 工作得很好,我可以很容易地得到 given 的作者Post

但是,如果我尝试Post在 JSON 响应中返回 ,它也会返回给我奇怪的属性,这些属性user似乎来自我user()调用 a 的方法belongsTo()

return response()->json(Post::find(2), 200);
{
    "id": 2,
    "title": "Amazing Post",
    "description": "Nice post",
    "author": "FooBar",
    "user": {
        "id": 4,
        "username": "FooBar"
    }
}

如果我使用attributesToArray()它按预期工作:

return response()->json(Post::find(2)->attributesToArray(), 200);
{
    "id": 2,
    "title": "Amazing Post",
    "description": "Nice post",
    "author": "FooBar"
}

此外,如果我删除 gettergetAuthorAttribute()$appends声明,我不会得到意外的user属性。

但是我不想每次都使用这个方法,如果我想返回我所有的Post使用,它不会使它工作:

return response()->json(Post::all(), 200);

有人知道我为什么要使用这个附加属性belongsTo吗?

标签: phplaravellumen

解决方案


  • 这种行为是因为性能。当你$post->user第一次调用时,Laravel 会从数据库中读取并保存以$post->relation[]备下次使用。所以下次 Laravel 可以从数组中读取它并防止再次执行查询(如果你在多个地方使用它会很有用)。

  • 另外,用户也是一个属性, 当您调用或时,Laravel 会合并$attributes和排列在一起$relations$model->toJson()$model->toArray()

Laravel 的模型源代码:

public function toArray()
{
    return array_merge($this->attributesToArray(), $this->relationsToArray());
}

public function jsonSerialize()
{
    return $this->toArray();
}

推荐阅读