将 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);
         }),
      ];
   }

   //...
}