Laravel:使用 belongsTo() 向我的模型添加意外属性
Laravel: Using belongsTo() add unexpected attributes to my Model
我正在使用 Lumen 编写 REST API。我的示例有 2 个模型 User
和 Post
。 Post
模型使用方法 belongsTo
获取创建此 post 的 User
模型。我的目标是定义一个 accessor,这样我就可以像 Post::find($id)->author
一样获得 post 的作者用户名。所以根据文档我这样做:
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 运行良好,我可以轻松获得给定 Post
的作者。
但是,如果我尝试在 JSON 响应中 return Post
,它也会 return 我奇怪的属性,如 user
似乎来了从我的 user()
方法调用 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"
}
此外,如果我删除 getter getAuthorAttribute()
和 $appends
声明,我不会得到意外的 user
属性。
但我不想每次都使用这种方法,如果我想 return 我所有的 Post
使用:
return response()->json(Post::all(), 200);
有人知道为什么我使用 belongsTo
获得这个附加属性吗?
此行为是性能问题。
当您第一次调用 $post->user
时,Laravel 从数据库中读取它并 将其保存在 $post->relation[]
中以供下次使用 。所以下次 Laravel 可以从数组中读取它并防止再次执行查询(如果你在多个地方使用它会很有用)。
另外,用户也是一个属性和Laravel合并
当您调用 $model->toJson()
或 $model->toArray()
时,$attributes
和 $relations
排列在一起
The Laravel's Model source code:
public function toArray()
{
return array_merge($this->attributesToArray(), $this->relationsToArray());
}
public function jsonSerialize()
{
return $this->toArray();
}
你的第一个方法很好,你只需要将 'user' 添加到 $hidden 数组
<?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',
'user', // <-- add 'user' here
];
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
public function getAuthorAttribute()
{
return $this->user->username;
}
}
您得到的模型将是:
{
"id": 2,
"title": "Amazing Post",
"description": "Nice post",
"author": "FooBar"
}
我正在使用 Lumen 编写 REST API。我的示例有 2 个模型 User
和 Post
。 Post
模型使用方法 belongsTo
获取创建此 post 的 User
模型。我的目标是定义一个 accessor,这样我就可以像 Post::find($id)->author
一样获得 post 的作者用户名。所以根据文档我这样做:
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 运行良好,我可以轻松获得给定 Post
的作者。
但是,如果我尝试在 JSON 响应中 return Post
,它也会 return 我奇怪的属性,如 user
似乎来了从我的 user()
方法调用 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"
}
此外,如果我删除 getter getAuthorAttribute()
和 $appends
声明,我不会得到意外的 user
属性。
但我不想每次都使用这种方法,如果我想 return 我所有的 Post
使用:
return response()->json(Post::all(), 200);
有人知道为什么我使用 belongsTo
获得这个附加属性吗?
此行为是性能问题。 当您第一次调用
$post->user
时,Laravel 从数据库中读取它并 将其保存在$post->relation[]
中以供下次使用 。所以下次 Laravel 可以从数组中读取它并防止再次执行查询(如果你在多个地方使用它会很有用)。另外,用户也是一个属性和Laravel合并 当您调用
$model->toJson()
或$model->toArray()
时,
$attributes
和 $relations
排列在一起
The Laravel's Model source code:
public function toArray() { return array_merge($this->attributesToArray(), $this->relationsToArray()); } public function jsonSerialize() { return $this->toArray(); }
你的第一个方法很好,你只需要将 'user' 添加到 $hidden 数组
<?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',
'user', // <-- add 'user' here
];
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
public function getAuthorAttribute()
{
return $this->user->username;
}
}
您得到的模型将是:
{
"id": 2,
"title": "Amazing Post",
"description": "Nice post",
"author": "FooBar"
}