Crear un búscador con Laravel y spatie/laravel-searchable.

Si, hay muchos tutoriales en internet sobre esto pero esta vez será algo rápido de implementar ;)

Ok, recientemente he estado trabajando en una aplicación que llegó a un punto que necesitaba un buscador.

Claro, existen cosas como Laravel Scout pero por ser un MVP el proyecto no cuenta con un budget que permita invertir en algolia.

Entonces, buscando siempre en los paquetes creados por la comunidad resaltan los de spatie, sus paquetes me han ayudado a resolver problemas de una forma mucho más rápida y eficiente.

El paquete que necesite para esto es:

1composer require spatie/laravel-searchable

La configuración de este paquete es sencilla, solo requiere que implementemos la interfaz Searchable en el modelo a usar, de la siguiente forma:

1<?php
2 
3namespace App\Models;
4 
5use Spatie\Searchable\Searchable;
6use Spatie\Searchable\SearchResult;
7use Illuminate\Database\Eloquent\Model;
8 
9class Post extends Model implements Searchable
10{
11 // other stuff
12 
13 public function getSearchResult(): SearchResult
14 {
15 return new SearchResult(
16 $this,
17 $this->title,
18 route('front.post.show', $this->slug)
19 );
20 }
21}

Acá básicamente lo que estamos haciendo es crear una nueva instancia de SearchResult dónde le pasamos como parámetros: el modelo en sí mismo, el título y la url del recurso.

Ahora creamos un controlador para poder tener acceso a la data desde nuestro frontend usando (por ejemplo) VueJS / ReactJS, Axios o Ajax. En mi caso, usé un Single Action Controller de la siguiente forma:

1<?php
2 
3namespace App\Http\Controllers;
4 
5use App\Models\Post;
6use Spatie\Searchable\Search;
7use App\Http\Controllers\Controller;
8 
9class ShowProfile extends Controller
10{
11 /**
12 * Handle the incoming request.
13 *
14 * @param \Illuminate\Http\Request $request
15 * @return \Illuminate\Http\Response
16 */
17 public function __invoke(Request $request)
18 {
19 $response = (new Search())
20 ->registerModel(Post::class, ['title'])
21 ->search($request->search);
22 
23 return response()->json($response);
24 }
25}

Ya lo único que queda es crear una ruta:

1Route::get('/search', 'Front\Search\SearchController')
2 ->name('front.search');

NOTA: este post es básicamente una traducción del readme del paquete spatie/laravel-searchable. Para más info, vayan al repo.

Angel Cruz's avatar
Autor
Angel Cruz