我有这个模型:
App\Controllers\ImageController.php
.....
$image = new Image;
$image->id = "pre_" . (string) Str::ulid()->toBase58();
$image->filename = $filename
$image->post_id= $post_id;
$image->save();
return $image->load("post:id,status,subject,body");
如果它工作正常,则返回以下内容:
{
"id": "pre_1BzVrTK8dviqA9FGxSoSnU",
"type": "document",
"filename": "v1BzVc3jJPp64e7bQo1drmL.jpeg",
"post_id": "post_1BzVc3jJPp64e7bQo1drmL",
"post": {
"id": "post_1BzVc3jJPp64e7bQo1drmL",
"status": "active"
....
}
....
}
App\Models\Image.php
class Image extends Model
{
use HasFactory;
public $incrementing = false;
public function post()
{
return $this->belongsTo(Post::class);
}
}
这里的问题是,我不希望它返回“post_id”字段,我想得到以下内容:
{
"id": "pre_1BzVrTK8dviqA9FGxSoSnU",
"type": "document",
"filename": "v1BzVc3jJPp64e7bQo1drmL.jpeg",
"post": {
"id": "post_1BzVc3jJPp64e7bQo1drmL",
"status": "active"
....
}
....
}
我试过这个:
return $image->select(["id", "type", "filename"])->load("post:id,status,subject,body");
它返回一个错误:
“message”:“调用未定义的方法Illuminate\Database\Eloquent\Builder::load()",
我该怎么办?
2条答案
按热度按时间mnowg1ta1#
你试过的代码
实际上有多个问题,并且将一些事情混合在一起。
第一个问题是,您已经有了一个图像模型,并试图只选择几列,这实际上将为另一个图像创建一个新的查询。您可以做的是在加载图像之前只选择所需的列,例如:
这个解决方案的问题将我们引向第二个问题:当你不选择
post_id
时,Laravel将无法加载关系,因为缺少外键。如果查询语句是正确的,它实际上会执行两个查询:
但是,由于在第一个查询中没有包含
post_id
,因此它不能作为第二个查询的参数使用,并且无法加载关系数据。解决方案1:API资源
使用API resource转换图像,然后再返回。这是最佳实践,因为它允许您将内部数据结构与公共数据结构解耦。它还将防止内部数据结构发生变化时(添加新列、重命名列、删除列等)发生不必要的API变化。
在您的情况下,解决方案可能非常简单:
可能的解决方案#2:隐藏字段
可以使用
$hidden
属性在模型中定义隐藏字段。这些字段不会序列化为JSON:或者,您可以使用
$visible
来定义白名单而不是黑名单。只有$visible
数组中的属性将被序列化:这种解决方案显然会影响整个应用程序,因此可能并不理想。
解决方案3:临时设置隐藏/可见属性
您也可以在控制器中临时设置
$hidden
或$visible
,而不是永久设置它们:cunj1qz12#
尝试使用和雄辩的API资源,使和格式和加载字段从关系,检查文档
并在控制器中调用此资源