Laravel - Comment effectuer une recherche en fonction des étiquettes dans une relation polymorphe beaucoup à plusieurs?

StackOverflow https://stackoverflow.com//questions/24024121

Question

J'ai un formulaire configuré avec une entrée de texte et une entrée multi-sélection. L'entrée multi-sélection a une liste des balises. Les balises sont configurées comme une relation polymorphe nombreuses à plusieurs. Pour aider à réduire les choses, ci-dessous est un contour de mes tables et mes modèles:

Tables:

org
   id - integer
   name - text
   ...

tags
   id - integer
   name - text

taggables
   tag_id - integer
   taggable_id - integer
   taggable_type - text

modèles:

class Org extends Eloquent
{
    ...

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


class Tag extends Eloquent
{
    ...

    public function org() 
    {
        return $this->morphedByMany('Org', 'taggable');
    }
}

dans mon fichier routes.php, j'essaie d'effectuer une recherche comme ...

$search = Input::get('keyword');
$searchTerms = explode(' ', $search);
$query = Org::query();
$fields = array('name', 'description', 'additional_info', 'website');

foreach ($searchTerms as $term)
{
    foreach ($fields as $field)
    {
        $query->orWhere($field, 'LIKE', '%'. $term .'%');
    }
}

if(Input::get('tags'))
{
    $tags = Input::get('tags');
    $query
        ->join('taggables', 'taggables.taggable_id', '=', 'org.id')
        ->where('taggables.taggable_type', '=', 'Org')
        ->join('tags', 'taggables.tag_id', '=', 'tags.id')
        ->groupBy('org.id');

    foreach ($tags as $tag)
    {
        $query->orWhere('tags.id', '=', $tag);
    }
}

$org = $query->get();

Cependant, cela ne fonctionne bien sûr pas. La recherche de mots-clés fonctionne bien, mais je ne sais pas comment ajouter une requête qui ne récupérera que les lignes contenant les balises associées spécifiées. La variable $ Tags est un tableau contenant les identifiants des balises.

Je veux renvoyer uniquement les lignes de la table Org qui ont au moins une des balises spécifiées dans le tableau.

mise à jour: J'ai mis à jour mon code et cela fonctionne en quelque sorte, mais il semble revenir à des étiquettes et non aux organisations associées - bien que je sente que je me rapproche de près. Voici le code pertinent que j'ai ajouté (ou simplement le regarder ci-dessus):

$query
    ->join('taggables', 'taggables.taggable_id', '=', 'org.id')
    ->join('tags', 'taggables.tag_id', '=', 'tags.id')
    ->where('taggables.taggable_type', '=', 'Org')
    ->whereIn('tags.id', $tags);

Mise à jour 2: Cela semble fonctionner comment je le veux, mais pour une raison quelconque, il récupère le nom de la balise au lieu du nom de l'organisation ...

$tags = Input::get('tags');
$query
    ->join('taggables', 'taggables.taggable_id', '=', 'org.id')
    ->where('taggables.taggable_type', '=', 'Org')
    ->join('tags', 'taggables.tag_id', '=', 'tags.id')
    ->groupBy('org.id');

foreach ($tags as $tag)
{
    $query->orWhere('tags.id', '=', $tag);
}

Était-ce utile?

La solution

J'ai eu le mot-clé + la recherche de tag fonctionnant de la manière suivante:

$query = Org::query();

// Search by keyword(s)
if(Input::get('keyword'))
{
    $search = Input::get('keyword');
    $searchTerms = explode(' ', $search);
    $fields = array('org.name', 'org.description', 'org.additional_info', 'org.website');

    foreach ($searchTerms as $term)
    {
        foreach ($fields as $field)
        {
            $query->orWhere($field, 'LIKE', '%'. $term .'%');
        }
    }
}

// Search for tag(s)
if(Input::get('tags'))
{
    $tags = Input::get('tags');
    $query
        ->join('taggables', 'taggables.taggable_id', '=', 'org.id')
        ->where('taggables.taggable_type', '=', 'Org')
        ->whereIn('taggables.tag_id', $tags)
        ->groupBy('org.id')
        ->orderBy(DB::raw('count(*)'), 'desc')
        ->orderBy('name', 'asc');
}

$org = $query->get();

Si un mot clé et deux balises sont entrés pour la recherche (par exemple), ceci renvoie ces organisations qui ont une ou plusieurs des balises, contiennent des mots qui sont comme le mot clé entré et trier les résultats afin que les organisations avecLes balises les plus assorties apparaîtront d'abord.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top