Crear un búscador con Laravel y spatie/laravel-searchable.
Este artículo tiene más de un año de antigüedad, el contenido pudiera estar obsoleto.
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 Searchable10{11 // other stuff12 13 public function getSearchResult(): SearchResult14 {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 Controller10{11 /**12 * Handle the incoming request.13 *14 * @param \Illuminate\Http\Request $request15 * @return \Illuminate\Http\Response16 */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.