trovare recensioni ha più di un tag. in relazione laravel polimorfica molti a molti

Aug 22 2020

ciao sto cercando di usare il polimorfico molti a molti ma in qualche modo non funziona non sono riuscito a ottenere recensioni correlate in relazione polimorfica molti a molti voglio ottenere una recensione per tag, selezionati dal cliente

Struttura della tabella:

review
> id - integer
> name - string

tags
> id - integer
> name - string

taggables
> tag_id - integer
> taggable_id - integer
> taggable_type - string

Modelli:

class Tag extends Eloquent
{
    public function reviews()
    {
        return $this->morphedByMany(Review::class, 'taggable');
    }

}

class Review extends Eloquent
{
    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
}

la richiesta del cliente [tag_id_1,tag_id_2,tag_id_3,tag_id_4]

la richiesta come [1, 2, 3, 4, 5] matrice di tag-chiave

se una recensione relativa a questi tag trova e ottiene la recensione, ho provato qualcosa del genere

Codice per le revisioni relative ai resi:

return Review::join('taggables', 'taggables.taggable_id', '=', 'reviews.id')
        ->where('taggables.taggable_type', '=', Review::class)
        ->whereIn('taggables.tag_id', [1, 2, 3, 4, 5])
        ->groupBy('reviews.id')
        ->orderBy('name', 'asc')
        ->get();

O:

Review::WhereHas('tags', function ($query) {
        $query->whereIn('tags_id', [1, 2, 3, 4, 5]);
    })->get();

il risultato di cui ho bisogno: le uniche recensioni che dovrebbero avere questi tag

review:{
name: "Review",
tags :[1, 2, 3, 4, 5]
}

laravel relazioni eloquenti molti-a-molti-polimorfici

Risposte

user3532758 Aug 22 2020 at 15:58

Se vuoi che la recensione abbia tutti i tag, questo è un modo per farlo:

$tagIds = [1,2,3,4,5];
$reviews = Review::query();
foreach($tagIds as $id){
 $reviews->whereHas('tags', function($query) use ($id) {
   return $query->where('id', $id);
 });
}
$reviewsWithAllThoseIds = $reviews->get(); 

//if you don't want to use foreach.
collect($tagIds)->each(function($id) use ($reviews){
    $reviews->whereHas('tags', function($q) use ($id) {
        return $q->where('id', $id);
    });
});

Questo dovrebbe darti le recensioni che hanno tutti i tag che hanno gli ID nell'array.

mohammadrezakhalifeh Aug 22 2020 at 15:04

hai un errore di battitura nella tua query.la forma corretta di taggables.tagable_iddovrebbe essere taggables.taggable_id. Non so se questo è il problema o no, ma suggerisco di scrivere il tuo codice come di seguito.

nel modello di revisione definire relazioni come questa:

public function tags()
{
    return $this->morphToMany(Tag::class, 'taggable','taggables','taggable_id','tag_id');
}

e nel modello Tag definire una relazione come:

public function reviews()
{
    return $this->morphedByMany(Review::class, 'taggable','taggables','tag_id','taggable_id');
}

e quando vuoi restituire le recensioni di un tag specifico, fallo come:

$tag=Tag::find(1);
$tagReviews=$tag->reviews;