将 Laravel Nova 过滤器应用于计算值
Apply Laravel Nova filter to Computed Value
我有一个 Laravel Nova 资源,它里面有一个名为视图的计算值。我想添加一个 Nova 过滤器,它可以影响计算值的结果(而不是查询本身),但不知道该怎么做。
我的计算值如下所示:
Text::make('Views', function() {
return $this->getViewsCount();
}),
我希望能够做类似的事情:
Text::make('Views', function() {
if(isset($filterValue)) {
return $this->getViewsBetween($filterValue);
} else {
return $this->getViewsCount();
}
}
您可以尝试从请求中获取过滤器值:
$queryFilters = $request->query('filters')
该参数是 base64 和 json 编码的,因此您必须先对其进行解码。
看看Laravel\Nova\Http\Requests\DecodesFilters
作为参考。
您的计算字段可能如下所示:
Text::make('Views', function () use ($request) {
$queryFilters = $request->query('filters');
$decodedFilters = collect(json_decode(base64_decode($queryFilters), true));
$computed = $decodedFilters->map(function ($filter) {
return $this->getViewsBetween($filter['value']);
});
if ($computed->isEmpty()) {
return $this->getViewsCount();
}
return $computed->implode(',');
})
更新:$decodedFilters
保存 class 和所选过滤器的值。
Illuminate\Support\Collection {
#items: array:1 [
0 => array:2 [
"class" => "App\Nova\Filters\UserType"
"value" => "admin"
]
]
}
关于冲突的相同问题 id
过滤器字段替换了模型 id
字段并且计算字段中的 $this->id
来自另一个 table,而不是来自模型。因此解决方案是使用别名从模型中重复 ->select([...])
查询(相同!)值。例如(用 userid
别名求解 user.id
字段)
型号
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
class User extends Model
{
//...
public function scopeMyScope($query, int $userId) : bool
{
return $query
->select('user.id', 'user.id as userid'/*,...*/)
->[...];
}
//...
过滤器
<?php
namespace App\Nova\Filters;
use Illuminate\Container\Container;
use Illuminate\Http\Request;
use Laravel\Nova\Filters\Filter;
class MyFilter extends Filter
{
//...
public function apply(Request $request, $query, $value)
{
//Same select fields as in model with userid, dont skip select in the filter!
return $query
->select('user.id', 'user.id as userid'/*,...*/)
->[...];
}
//...
资源
<?php
namespace App\Nova;
use App\Nova\Filters\MyFilter;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\HasMany;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
class User extends \App\Nova
{
//...
public function fields(Request $request)
{
return [
//userid
Boolean::make('some', function () {
return \App\Models\User::myScope($this->userid);
}),
];
}
//...
}
我有一个 Laravel Nova 资源,它里面有一个名为视图的计算值。我想添加一个 Nova 过滤器,它可以影响计算值的结果(而不是查询本身),但不知道该怎么做。
我的计算值如下所示:
Text::make('Views', function() {
return $this->getViewsCount();
}),
我希望能够做类似的事情:
Text::make('Views', function() {
if(isset($filterValue)) {
return $this->getViewsBetween($filterValue);
} else {
return $this->getViewsCount();
}
}
您可以尝试从请求中获取过滤器值:
$queryFilters = $request->query('filters')
该参数是 base64 和 json 编码的,因此您必须先对其进行解码。
看看Laravel\Nova\Http\Requests\DecodesFilters
作为参考。
您的计算字段可能如下所示:
Text::make('Views', function () use ($request) {
$queryFilters = $request->query('filters');
$decodedFilters = collect(json_decode(base64_decode($queryFilters), true));
$computed = $decodedFilters->map(function ($filter) {
return $this->getViewsBetween($filter['value']);
});
if ($computed->isEmpty()) {
return $this->getViewsCount();
}
return $computed->implode(',');
})
更新:$decodedFilters
保存 class 和所选过滤器的值。
Illuminate\Support\Collection {
#items: array:1 [
0 => array:2 [
"class" => "App\Nova\Filters\UserType"
"value" => "admin"
]
]
}
关于冲突的相同问题 id
过滤器字段替换了模型 id
字段并且计算字段中的 $this->id
来自另一个 table,而不是来自模型。因此解决方案是使用别名从模型中重复 ->select([...])
查询(相同!)值。例如(用 userid
别名求解 user.id
字段)
型号
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
class User extends Model
{
//...
public function scopeMyScope($query, int $userId) : bool
{
return $query
->select('user.id', 'user.id as userid'/*,...*/)
->[...];
}
//...
过滤器
<?php
namespace App\Nova\Filters;
use Illuminate\Container\Container;
use Illuminate\Http\Request;
use Laravel\Nova\Filters\Filter;
class MyFilter extends Filter
{
//...
public function apply(Request $request, $query, $value)
{
//Same select fields as in model with userid, dont skip select in the filter!
return $query
->select('user.id', 'user.id as userid'/*,...*/)
->[...];
}
//...
资源
<?php
namespace App\Nova;
use App\Nova\Filters\MyFilter;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\HasMany;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
class User extends \App\Nova
{
//...
public function fields(Request $request)
{
return [
//userid
Boolean::make('some', function () {
return \App\Models\User::myScope($this->userid);
}),
];
}
//...
}