Ajouter une recherche sur son application Laravel

C’est souvent un point important sur une application. La recherche peut se faire sur plusieurs critères. Parfois, on a besoin de lancer la recherche sur plusieurs tables de la base de données. C’est ce que nous allons voir dans cet article.

Dans un premier temps, on va créer la class App\Search. Le but ici va être d’avoir une méthode par type de recherche :

<?php

namespace App\Search;

use App\Address;
use App\User;

/**
 * Class Search.
 */
class Search
{

    /**
     * @var User
     */
    protected $user;
    /**
     * @var Address
     */
    protected $address;
    /**
     * Search constructor.
     *
     * @param User         $user
     * @param Address      $address
     */
    public function __construct(
        User $user,
        Address $address
    ) {
        $this->user = $user;
        $this->address = $address;
    }

    /**
     * @param      $query
     *
     * @return mixed
     */
    public function users($query)
    {
        return $this->user->search($query);
    }

    /**
     * @param      $query
     *
     * @return mixed
     */
    public function addresses($query)
    {
        return $this->address->search($query);
    }
}

En fait, on injecte les modèles dont on va avoir besoin. On va faire en sorte d’avoir une méthode générique qui contiendra le scope pour lancer la recherche sur le modèle.

Ensuite, il nous faut un Service Provider, qui va s’appeler : SearchServiceProvider. Au hasard ! On va ensuite enregistrer la clé search sur notre appli, et indiquer ce qu’elle doit retourner. Ca sera notre classe Search, et on va pouvoir lui injecter les modèles du constructeur.
La méthode register resemble donc à ceci :

/**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('search', function () {

            return new Search(new User(), new Address());

        });
    }

Le Trait va maintenant nous aider à installer la pagination, et à insérer automatiquement la méthode search déclarée dans les fonction de la classe Search.

<?php

namespace App\Tenant;

/**
 * Class Searchable
 * @package App\Tenant
 */
trait Searchable
{

    /**
     * @var int
     */
    protected $pagination = 30;

    /**
     * @param      $query
     * @param $search
     * @param bool $pagination
     * @return mixed
     */
    public function scopeSearch($query, $search, $pagination = false)
    {
        if (is_integer($pagination)) {
            $this->pagination = $pagination;
        }

        return $this->searchInAvailableProperty($search)->orderBy($this->getKeyName(), 'desc')->paginate($pagination);

    }
}

Il faudra penser à enregistrer le service provider et la facade dans le fichier config.php. Maintenant, posons un exemple de requête :

/**
     * @param $query
     * @param $search
     *
     * @return mixed
     */
    public function scopeSearchInAvailableProperty($query, $search)
    {

        return $query->where(function ($q) use ($search) {

            $q->where('id', '=', (int)"{$search}")
                ->orWhere('email', 'like', "{$search}%")
                ->orWhere('last_name', 'like', "{$search}%")
                ->orWhere('first_name', 'like', "{$search}%");

        });
    }

De cette manière, on va pouvoir lancer la recherche sur les 3 champs, en évitant le problème du orWhere avec le SoftDelete.
Il faut ensuite penser à ajouter l’usage du Trait créé au dessus.

On ajoute une requête également sur le modèle Address. A partir de maintenant, rien ne vous empêche d’avoir une méthode all() dans App\Search, qui va chainer les recherches dans différentes clés.

Maintenant créez simplement un controller pour la recherche, et vous pouvez utiliser la facade soit avec Search::users($request->get(‘search’)); soit Search::all($request->get(‘search’)); au besoin.

Vous avez un nouveau modèle dans lequel vous devez lancer la recherche ? Ajoutez use Searchable, la requête, et ce modèle dans le service provider ainsi que dans la classe recherche. Vous pouvez même ajouter une pagination différente en cas de besoin, simplement en modifiant la requête. Et c’est tout !

Recherches utilisées pour trouver cet article :recherche avec laravel
metrogeek

Comments 1

  1. Merci pour ce petit tuto, je vais me le mettre de coté car j’ai bien envie d’ajouter de la recherche sur mon site sous laravel, donc ca me sera très utile ! Au plaisir de te relire à nouveau 😉

Laisser un commentaire