Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search polymorphic relation (tags) #222

Open
Shi974 opened this issue Jun 2, 2020 · 4 comments
Open

Search polymorphic relation (tags) #222

Shi974 opened this issue Jun 2, 2020 · 4 comments

Comments

@Shi974
Copy link

Shi974 commented Jun 2, 2020

Hello ! Is there any way to search polymorphic relationship ?

For instance, I am using spatie/laravel-tags package and this adds a polymorphic relationship between my models and the tags table.

So I have those tables and my models : dispositifs, infrastructures, etc. which are tagged and which can be searched.

Taggables

  • tag_id
  • taggable_type
  • taggable_id

Tags

  • id
  • name (json datatype for translations)
  • slug
  • type
    [...]

How could I search for tags please?

So far, I have this, but it does not seem to work. When I search for a "tag", the results returned are all the models and no point ordering is done ...

protected $searchable = [
        'columns' => [
            'dispositifs.di_sigle' => 10,
            'dispositifs.di_libelle' => 10,
            'dispositifs.di_objectif' => 6,
            'dispositifs.di_description' => 7,
            'dispositifs.di_condition' => 4,
            'dispositifs.di_procedure' => 4,
            'dispositifs.di_info' => 5,
	    'acteurs.acteur_libelle' => 8,
	    'tags.name' => 8,
        ],
        'joins' => [
			'operateur_dispo' => ['dispositifs.di_id', 'operateur_dispo.operateur_dispositif_id'],
			'acteurs' => ['operateur_dispo.operateur_acteur_id', 'acteurs.acteur_id'],
			'taggables' => ['taggables.tag_id','taggables.taggable_id'],
			'tags' => [ 'tags.id','taggables.tag_id'],
        ],
];

Thank you in advance and thanks to @nicolaslopezj for this awesome package ! 😁 👍

@GORAZIZYAN98
Copy link

GORAZIZYAN98 commented Jun 12, 2020

@Shi974 hey!
this is my working example
In model Game
wich hast morph relation like

    public function translations()
    {
        return $this->morphMany(Translation::class, 'translatable');
    }

 protected $searchable = [
        'columns' => [
            'translation.text' => 10,
        ],
        'joins' => [
            'translation' => ['translation.translatable_id', 'game.id'],
        ],
    ];

@Shi974
Copy link
Author

Shi974 commented Jun 16, 2020

Hey @GORAZIZYAN98 ! Thanks for your answer !
I forgot to use the relationship function. I fixed that thanks to you. ✔️
But I still have an issue. The search works but when I search for a tag, it returns only one element instead of several.
Also, it's really weird, I sometimes get results that are not taggued at all. 🤔

public function tags() {
        return $this -> morphToMany('\Spatie\Tags\Tag', 'taggable');
}

SEARCH

'columns' => [
            'dispositifs.di_sigle' => 10,
            'dispositifs.di_libelle' => 10,
            'dispositifs.di_objectif' => 6,
            'dispositifs.di_description' => 7,
            'dispositifs.di_condition' => 4,
            'dispositifs.di_procedure' => 4,
            'dispositifs.di_info' => 5,
	    'acteurs.acteur_libelle' => 8,
	    'tags.name' => 10,
	    'tags.slug' => 10,
	    'tags.type' => 8,
        ],
        'joins' => [
	    'operateur_dispo' => ['dispositifs.di_id', 'operateur_dispo.operateur_dispositif_id'],
	    'acteurs' => ['operateur_dispo.operateur_acteur_id', 'acteurs.acteur_id'],
	    'tags' => ['tags.id', 'dispositifs.di_id'],
       ]

If anyone has a little idea, I would be grateful 😄

@sneakylenny
Copy link

I did it like this:

protected $searchable = [
    /**
     * Columns and their priority in search results.
     * Columns with higher values are more important.
     * Columns with equal values have equal importance.
     *
     * @var array
     */
    'columns' => [
        'dispositifs.di_sigle' => 10,
        // ...
        'tags.name' => 10,
        'tags.slug' => 10,
        'tags.type' => 8,
    ],
    'joins' => [
        'taggables' => ['dispositifs.id', 'taggable.taggable_id'], // Join the pivot
        'tags' => ['taggables.tag_id', 'tags.id'], // Get tags based on joined pivot, now you can use this in "columns"!
    ]
];

To explain what I did:
First, I joined the pivot (taggables) where the connection between dispositifs and tags is made.
Next, from taggables I get the tag by the tag_id that is located on the joined pivot.
Tags are not searchable yet, but sincetags is now in the field list, we can add the attributes in the searchable 'columns' array.
Viola, tags are now searchable! 😃

Downsights:
Since taggable is supposed to make use of both taggable_id and taggable_type in combination. I'm not sure if this will conflict if resources have the same taggable_id. 🤔

I hope this will be useful to someone! 😄

@montesilva
Copy link

protected $searchable = [
    /**
     * Columns and their priority in search results.
     * Columns with higher values are more important.
     * Columns with equal values have equal importance.
     *
     * @var array
     */
    'columns' => [
        'dispositifs.di_sigle' => 10,
        // ...
        'tags.name' => 10,
        'tags.slug' => 10,
        'tags.type' => 8,
    ],
    'joins' => [
        'taggables' => ['dispositifs.id', 'taggables.taggable_id'], // Join the pivot
        'tags' => ['tags.id', 'taggables.taggable_id', 'taggables.taggable_type', Taggable::class] // Join taggable_id and _type
    ]
];

I used a lot of polymorphic relations in my projects, and came accross the same problem.
This solution makes use of both, taggable_id and taggable_type, so you only get resources from the type you pass,
in this case Taggable.

If you dont integrate the taggable_type, you will conflict.

If you use Relation::morphMap you must insert the string equivalent for the class instead of Taggable::class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants