Laravel: URL amigables (parte 18)

Laravel: URL amigables (parte 18)

Archivos:

  • database/migrations
  • database/factories

Crear el campo slug

Genramos un nuevo campo dentro de la migración de la tabla cursos, llamado «slug»

    public function up()
    {
        Schema::create('cursos', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('slug');
            $table->text('description');
            $table->text('categoria');
            $table->timestamps();
        });
    }

Editamos el factory de esta tabla:

    public function definition()
    {
        return [
            //
            'name'=>$this->faker->sentence(),
            'slug'=>Str::slug($this->faker->sentence(),'-'),
            'categoria'=>$this->faker->randomElement(['Desarrollo web','Diseño web']),
            'description'=>$this->faker->paragraph()
        ];

Hemos llamado a la clase Str y a su método slug. Cambiará todas las mayúsculas por minúsculas y sustituirá los espacios por guiones (porque hemos establecido un guión como segundo parámetro).

En este caso tendremos un slug distinto al título, y queremos que sea el mismo, con lo que lo podemos poner así:

public function definition()
    {
        $name =$this->faker->sentence();

        return [
            //
            'name'=>$name,
            'slug'=>Str::slug($name,'-'),
            'categoria'=>$this->faker->randomElement(['Desarrollo web','Diseño web']),
            'description'=>$this->faker->paragraph()
        ];
    }

No podemos olvidar llamar a la clase Str al principio del archivo, si no lo ha autorrellenado Intelephense:

use Illuminate\Support\Str;

Luego migramos para ver los cambios en la base de datos:

php artisan migrate:fresh --seed

Uso del campo slug

Abrimos la vista index de los cursos, comprobemos la url actual:

@foreach ($cursos as $curso)

        <li>
         <a href="{{route('cursos.show', $curso->id)}}">{{$curso->name}}</a> 
         </li>
          {{route('cursos.show', $curso->id))}}

        @endforeach

Recordamos que en Laravel podemos llamar a la id directamente de la siguiente manera, ya que el recurso de llamar a la id es muy utilizado y se puede hacer directamente así:

@foreach ($cursos as $curso)

        <li>
         <a href="{{route('cursos.show', $curso)}}">{{$curso->name}}</a> 
         </li>
          {{route('cursos.show', $curso))}}

        @endforeach

LA id se la pasamos al controlador mediante la variable curso. Necesitaríamos que cuando utilicemos el método route y le pasemos el objeto curso, en vez de la id, recupere el slug del objeto. Devolverá el registro cuyo slug coincida con lo que le pasemos por la url.

Vamos al modelo Curso, que vemos que se extiende de la clase Model.

Vemos que uno de los muchos métodos que tiene es getroutekeyname:

     public function getRouteKeyName()
    {
        return $this->getKeyName();
    }

Podríamos modificar este mnétodo tal que así, para lograr lo que queremos:

     public function getRouteKeyName()
    {
       // return $this->getKeyName();
 return 'slug';
    }

Pero lo mejor es hacerlo en el modelo Curso:

Recursos:

Enlace de Youtube: https://www.youtube.com/watch?v=VYuthGIhrS0&list=PLZ2ovOgdI-kWWS9aq8mfUDkJRfYib-SvF&index=25