klepak / nova-multiselect-filter

Multiselect filter for Laravel Nova
14 stars 18 forks source link

using filter with spatie tags package #8

Closed breizhwave closed 4 years ago

breizhwave commented 4 years ago

Hi, I am using this filter to show records that have a tag from spatie's famous packages

https://docs.spatie.be/laravel-tags/v2/introduction/ https://github.com/spatie/nova-tags-field

trying to build the query (full filter code below) brings the following error

"Argument 1 passed to Illuminate\Database\Eloquent\Builder::getBelongsToRelation() must be an instance of Illuminate\Database\Eloquent\Relations\MorphTo, instance of Illuminate\Database\Eloquent\Relations\MorphToMany given" `

namespace App\Nova\Filters;

use Illuminate\Http\Request; use Laravel\Nova\Filters\Filter; use Klepak\NovaMultiselectFilter\NovaMultiselectFilter;

class Tags extends NovaMultiselectFilter { /**

breizhwave commented 4 years ago

hey found by myself I think to be confirmed but seems to work

public function apply(Request $request, $query, $value) { return $query->whereHas('tags', function(Builder $query) use ($value) { $query->whereIn('tags.id', $value); }); }

vesper8 commented 4 years ago

thanks for putting me on the right track. For me this is what works best to allow me to use only the tag names and allow me to make sure if I select multiple tags that they are all included:

You could also use withAnyTags, withAllTags and withAnyTagsOfAnyType

    public function apply(Request $request, $query, $value)
    {
        return $query->withAllTagsOfAnyType($value);
    }

    public function options(Request $request)
    {
        $tags = Tag::all();

        return $tags->map(function ($tag) {
            return [
                'name' => $tag->name,
                'value' => $tag->name,
            ];
        });
    }
olivM commented 2 years ago

i created a dedicated filter package for spatie/laralve-tags : https://github.com/Mahi-Mahi/SpatieTagsNovaFilter with support for async autocomplete

sfinktah commented 1 year ago

@olivM Your package doesn't work with Nova 4, but I might look at updating it.

@breizhwave You were exactly where I was when I gave up and googled the problem, thanks!

@vesper8 Yours was the magic solution, though it didn't work as shipped, a variant did. I don't ever recall a time where options were returned using name, value pairs.

Here is a complete Nova Filter, for clarity. (Laravel 9, Nova 4).

namespace App\Nova\Filters;

use Laravel\Nova\Http\Requests\NovaRequest;
use Outl1ne\NovaMultiselectFilter\MultiselectFilter;
use Spatie\Tags\Tag;

class SiteTagFilter extends MultiselectFilter
{
    // XXX: comment this out!
    // public $component = 'select-filter';

    public function apply(NovaRequest $request, $query, $value)
    {
        ## without tag types
        return $query->withAllTagsOfAnyType($value);
        ## with tag types
        // return $query->withAllTags($value, 'site');
    }

    public function options(NovaRequest $request)
    {
        ## without tag types
        return Tag::all()->pluck('name', 'name')->all();
        ## with tag types
        // return Tag::withType('site')->get()->pluck('name', 'name')->all();
    }
}