向雄辩的资源添加过滤器以有条件地附加关系 [英] Adding filter to eloquent resource to attach relationship conditionally
问题描述
Laravel 5.8 PHP 7.4
Laravel 5.8 PHP 7.4
我想像这样有条件地加载关系
I want to load the relationships conditionally like
http://127.0.0.1:8000/api/posts
和
http://127.0.0.1:8000/api/posts/1 are my end points now, I want to load comments like
http://127.0.0.1:8000/api/posts/?include=comments
和
http://127.0.0.1:8000/api/posts/1/?include=comments
如果存在查询参数,则只有该参数才能加载带有帖子的评论,或者仅加载帖子/帖子
If the query parameter is there, only then it should load comments with posts or it should load only posts/post
我通过引用博客文章
现在, RequestQueryFilter
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
class RequestQueryFilter
{
public function attach($resource, Request $request = null)
{
$request = $request ?? request();
return tap($resource, function($resource) use($request) {
$this->getRequestIncludes($request)->each(function($include) use($resource) {
$resource->load($include);
});
});
}
protected function getRequestIncludes(Request $request)
{
// return collect(data_get($request->input(), 'include', [])); //single relationship
return collect(array_map('trim', explode(',', data_get($request->input(), 'include', [])))); //multiple relationships
}
}
和助手
<?php
if ( ! function_exists('filter') ) {
function filter($attach)
{
return app('filter')->attach($attach);
}
}
?>
在PostController中
in PostController
public funciton show(Request $request, Post $post) {
return new PostResource(filter($post));
}
但是当我尝试检索
http://127.0.0.1:8000/api/posts/1/?include=comments getting no comments, with no error in log
解决方法将是PostResource
A work around will be PostResource
public function toArray($request)
{
// return parent::toArray($request);
$data = [
'id' => $this->id,
'name' => $this->title,
'body' => $this->content,
];
$filter = $request->query->get('include', '');
if($filter){
$data[$filter] = $this->resource->$filter;
}
return $data;
}
推荐答案
我想像这样有条件地加载关系
I want to load the relationships conditionally like
使用load()
调用进行懒惰的渴望加载
Lazy Eager加载完成的最终结果与Laravel中的with()
相同,但是不是自动完成的. 例如:
Lazy Eager Loading using the load()
call
The Lazy Eager Loading accomplishes the same end results as with()
in Laravel, however, not automatically. For example:
?include=comments
// Get all posts.
$posts = Post::without('comments')->all();
if (request('include') == 'comments')) {
$posts->load('comments');
}
return PostResource::collection($posts);
或者,您可以要求include
查询字符串为数组:
Alternativelly, you could require the include
query string to be an array:
?include[]=comments&include[]=tags
// Validate the names against a set of allowed names beforehand, so there's no error.
$posts = Post::without(request('includes'))->all();
foreach (request('includes') as $include) {
$posts->load($include);
}
return PostResource::collection($posts);
仅当您定义模型以自动渴望加载要有条件加载的关系时,才需要调用 without()
.
The call without()
is only required in case you defined your model to automatically eager load the relationships you want to conditionally load.
public function toArray($request) {
$data = [...];
foreach ($this->relations as $name => $relation)
{
$data[$name] = $relation;
}
return $data;
}
这篇关于向雄辩的资源添加过滤器以有条件地附加关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!