问题描述
我不确定,这里发生了什么。我有一组模型 ID,但如果省略了特定 ID,我想回退使用所有模型。
use App\Models\Post;
function list($ids = [])
{
$posts = collect($ids)->whenEmpty(function ($posts) {
return Post::all()->pluck('id');
})->each(function ($item,$key) {
$post = Post::findOrFail($item);
});
}
如果我通过 $ids
传递特定 ID,效果很好。但是当我将它留空时,Post::all()->pluck('id');
内的 whenEmpty()
返回空。但是如果我在集合外调用 Post::all()->pluck('id');
它工作得很好。所以我认为这可能是某种范围问题,因为它在闭包内,但将其更改为:
use App\Models\Post;
function list($ids = [])
{
$posts = collect($ids)->whenEmpty(function ($posts) {
return \App\Models\Post::all()->pluck('id');
})->each(function ($item,$key) {
dd($item);
});
}
仍然显示为 ""
如果我 dd()
整个集合只是:
[
0 => ""
]
所以即使提供整个命名空间也不起作用。我在这里错过了什么?
解决方法
我知道这可能不会直接回答您的问题(因为我会以不同的方式来做这件事),但也许它对您或处于相同情况的其他人有帮助。
我要做的是使用 Request 类来验证引入的 ID,如下所示:
use Illuminate\Validation\Rules\Exists;
class PostsRequests extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'ids' => ['array'],'ids.*' => ['numeric',new Exists('posts','id')],];
}
/**
* Handle a passed validation attempt.
*
* @return void
*/
public function passedValidation()
{
$this->ids = $this->validated()['ids'];
}
}
这样可以确保数组中引入的所有 ID 都存在于帖子表中。否则,请求失败。
既然您知道所有 ID 都是有效的,您可以简单地检查数组是否为空:
class PostController extends Controller
{
public function list(PostsRequests $request)
{
$posts = empty($request->ids) ? Post::all() : Post::whereIn('id',$request->ids])->get();
}
}
更新
由于 ID 数组不是来自请求,您可以在控制器本身中使用验证器:
use Illuminate\Validation\Rules\Exists;
use Illuminate\Support\Facades\Validator;
class PostController extends Controller
{
public function list(array $ids)
{
Validator::make($ids,[
'*' => ['numeric',])->validate();
$posts = empty($ids) ? Post::all() : Post::whereIn('id',$ids])->get();
}
}
,
这是一种方法
function list(array $ids = [])
{
if(empty($ids)) $posts = Post::all();
else $posts = collect($ids)->map(function($id) {
return Post::findOrFail($id);
});
$posts->each(...); /* collection */
}
如果您想使用 whenEmpty()
function list(array $ids = [])
{
collect($ids)->map(function($id) {
return Post::findOrFail($id);
})->whenEmpty(function($posts){
return $posts = Post::all();
})->each(...);
}