--- title: Laravel [04] (Seeders i Relacions NaN) tags: daw, Laravel, migrations, M7 --- <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licencia de Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br />Este obra está bajo una <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional</a>. [Enllaç a Hackmk.io](https://hackmd.io/@JdaXaviQ/H1m28_2-n) ## Laravel [04] (Seeders i Relacions NaN). ### Migracions amb relacions N-N: Suposem que tenim una aplicació web per a una biblioteca i volem mantenir un registre de l'ús que fan els usuaris de cada llibre. Per a això, necessitem crear dues taules: una per als llibres i una altra per als usuaris. A més a més, necessitem una tercera taula per a la relació many-to-many entre els llibres i els usuaris, que mantindrà un registre dels préstecs de llibres per part dels usuaris. Migracions necessàries: 1. La migració "create_llibres_table" per a la taula de llibres, que contindrà les columnes per a la clau primària (id), el títol del llibre, l'autor, la data de publicació, etc. 2. La migració "create_usuaris_table" per a la taula d'usuaris, que contindrà les columnes per a la clau primària (id), el nom d'usuari, la contrasenya, l'adreça de correu electrònic, etc. 3. La migració "create_prestecs_table" per a la taula de prestecs, que contindrà les columnes per a la clau primària (id), les claus estrangeres per a les taules de llibres i usuaris (llibre_id i usuari_id) i qualsevol altra informació rellevant, com la data de préstec, la data de retorn, etc. Una vegada creades les taules a través de les migracions i configurades les relacions many-to-many entre els models de Laravel, serà possible realitzar consultes per obtenir informació sobre quins usuaris han agafat quins llibres, quins llibres estan actualment prestats, etc. Desprès de les corresponents crides a artisan per a generar la base dels fitxers de les migracions, ampliarem amb el següent codi: 1. Migració create_llibres_table: ```python= Schema::create('llibres', function (Blueprint $table) { $table->id(); $table->string('titol'); $table->string('autor'); $table->date('data_publicacio'); $table->timestamps(); }); ``` 2. Migració create_usuaris_table: ```python= Schema::create('usuaris', function (Blueprint $table) { $table->id(); $table->string('nom_usuari')->unique(); $table->string('contrasenya'); $table->string('email')->unique(); $table->timestamps(); }); ``` 3. Migració create_prestecs_table: ```python= Schema::create('prestecs', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('llibre_id'); $table->unsignedBigInteger('usuari_id'); $table->date('data_prestec'); $table->date('data_retorn')->nullable(); $table->timestamps(); $table->foreign('llibre_id')->references('id')->on('llibres')->onDelete('cascade'); $table->foreign('usuari_id')->references('id')->on('usuaris')->onDelete('cascade'); }); ``` :eye: :fire: Abans d'executar les migracions per a obtenir les taules a la base de dades assegureu-vos-en d'haber configurat correctament el fitxer .env per a que apunti a la base de dades adient. ```yaml= DB_CONNECTION=mysql DB_HOST=localhost DB_PORT=3306 DB_DATABASE=relacions DB_USERNAME=laravel DB_PASSWORD=1234 ``` Ara és el torn dels models, completeu amb el següent codi després de la generació automàtica amb artisan: ```php= <?php // Model Usuari namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Usuari extends Model { use HasFactory; protected $fillable = [ 'nom_usuari', 'contrasenya', 'email', ]; public function llibres() { return $this->belongsToMany(Llibre::class, 'prestecs')->withPivot('data_prestec', 'data_retorn'); } } ?> --- <?php // Model Llibre namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Llibre extends Model { use HasFactory; protected $fillable = [ 'titol', 'autor', 'data_publicacio', ]; public function usuaris() { return $this->belongsToMany(Usuari::class, 'prestecs')->withPivot('data_prestec', 'data_retorn'); } } ?> --- <?php // Model Prestec namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Prestec extends Model { use HasFactory; protected $fillable = [ 'llibre_id', 'usuari_id', 'data_prestec', 'data_retorn', ]; public function llibre() { return $this->belongsTo(Llibre::class); } public function usuari() { return $this->belongsTo(Usuari::class); } } ?> ``` :fire: S'ha afegit la funció "withPivot" per a incloure les columnes "data_prestec" i "data_retorn" de la taula "prestecs" en la relació. ### Seeders. Abans de continuar amb les rutes, omplirem les taules amb dades de prova, però en aquest cas en lloc d'inventar-nos cadascú les dades i inserir-les des de la pròpia consola del SGBD, ho farem a l'estil Laravel: emprant els anomenats __seeders__. #### Què són els seeders? En Laravel, els seeders són eines que ens permeten omplir la base de dades amb dades de prova o dades inicials per a l'aplicació. S'utilitzen principalment per a desenvolupament i prova, ja que ens permeten simular la presència de dades reals a la base de dades sense haver de crear-les manualment. #### Com funcionen els seeders? Els seeders es defineixen com a classes de PHP dins de la carpeta "database/seeds". Cada seeder pot contenir un o més registres de dades, que es creen a través de la funció "run" que es defineix en el seeder. Per a crear els fitxers __seeders__ utilitzarem les següents comandes: ```bash= isard@ubuntu:~/src/relacionsNaN$ php artisan make:seeder UsuariSeeder INFO Seeder [database/seeders/UsuariSeeder.php] created successfully. isard@ubuntu:~/src/relacionsNaN$ php artisan make:seeder LlibreSeeder INFO Seeder [database/seeders/LlibreSeeder.php] created successfully. isard@ubuntu:~/src/relacionsNaN$ php artisan make:seeder PrestecSeeder INFO Seeder [database/seeders/PrestecSeeder.php] created successfully. isard@ubuntu:~/src/relacionsNaN$ ``` Per exemple, un seeder per a la taula "usuaris" podria tenir el següent codi: ```php= use Illuminate\Database\Seeder; use App\Models\Usuari; use Illuminate\Support\Facades\Hash; class UsuariSeeder extends Seeder { public function run() { Usuari::create([ 'nom_usuari' => 'user1', 'contrasenya' => Hash::make('password1'), 'email' => 'user1@example.com', ]); Usuari::create([ 'nom_usuari' => 'user2', 'contrasenya' => Hash::make('password2'), 'email' => 'user2@example.com', ]); // afegir més registres segons sigui necessari } } ``` Seeder per a la taula llibres: ```php= use Illuminate\Database\Seeder; use App\Models\Llibre; class LlibreSeeder extends Seeder { public function run() { Llibre::create([ 'titol' => 'La sombra del viento', 'autor' => 'Carlos Ruiz Zafón', 'data_publicacio' => '2001-01-01', ]); Llibre::create([ 'titol' => 'El nombre del viento', 'autor' => 'Patrick Rothfuss', 'data_publicacio' => '2007-03-27', ]); // afegir més registres segons sigui necessari } } ``` Seeder per a la taula prestecs: ```php= namespace Database\Seeders; use Illuminate\Database\Seeder; use App\Models\Prestec; class PrestecSeeder extends Seeder { public function run() { Prestec::create([ 'llibre_id' => 1, 'usuari_id' => 1, 'data_prestec' => '2023-04-20', 'data_retorn' => '2023-05-20', ]); Prestec::create([ 'llibre_id' => 2, 'usuari_id' => 2, 'data_prestec' => '2023-04-22', 'data_retorn' => '2023-05-22', ]); Prestec::create([ 'llibre_id' => 1, 'usuari_id' => 2, 'data_prestec' => '2023-04-23', 'data_retorn' => '2023-05-23', ]); } } ``` :fire: :fire: :fire: A PrestecSeeder m'he tirat un triple confiant en que les ids dels nous llibres i usuaris siguin 1 i 2 en ambdòs casos. :drum_with_drumsticks: Endavant la execució dels seeders: ```bash= isard@ubuntu:~/src/relacionsNaN$ php artisan db:seed --class=UsuariSeeder; php artisan db:seed --class=LlibreSeeder; php artisan db:seed --class=PrestecSeeder INFO Seeding database. INFO Seeding database. INFO Seeding database. isard@ubuntu:~/src/relacionsNaN$ ``` Ara, ja podem afegir les rutes i gaudir de la nostra aplicació, però de crear rutes ja en sabeu ;-)