Laravel problem with pivot table

1

I have two tables: one for travel and another for clients. In the pivot table it relates to each other in ManyToMany.

In the migration of the pivot table I have the following:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCustomerTourTable extends Migration
{
    public function up()
    {
        Schema::create('customer_tour', function (Blueprint $table) {
            $table->increments('id');
            /** Satisfacción */
            $table->char('satisfaccion', 1);
            /** Los campos de fechas */
            $table->timestamps();
            $table->softDeletes();
            /** La definición de los campos que se usarán como claves foráneas */
            $table->integer('customer_id')->unsigned();
            $table->integer('tour_id')->unsigned();
            /** La declaración de las claves foráneas en los campos necesarios. */
            $table->foreign('customer_id')->references('id')->on('customers');
            $table->foreign('tour_id')->references('id')->on('tours');
        });
    }

    public function down()
    {
        Schema::dropIfExists('customer_tour');
    }
}

What matters to me is the satisfaction field, where the degree of customer satisfaction with the trip will be recorded. In the factory I have the following:

<?php

use Faker\Generator as Faker;

$factory->define(App\CustomerTour::class, function (Faker $faker) {
    return [
        'satisfaccion' => $faker->randomElement(['A', 'B', 'C'])
    ];
});

In the Tour.php model (that of the trips) I have added the following (only the customers method):

public function customers()
{
    return $this->belongsToMany(Customer::class)->withTimeStamps()->using('App\CustomerTour')->withPivot('satisfaccion');
}

In the client model ( Customer.php ) I have the method tours asi;

public function tours()
{
    $this->belongsToMany(Tour::class)->withTimeStamps()->using('App\CustomerTour')->withPivot('satisfaccion');
}

The model CustomerTour.php (that of the pivot table) is as follows:

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\SoftDeletes;

class CustomerTour extends Pivot
{
    use SoftDeletes;
    protected $table = 'customers';
    protected $fillable = [
        'satisfaccion',
        'created_at',
        'updated_at'
    ];
    protected $attributes = [
        'satisfaccion'
    ];
    protected $guarded = [
        'id',
        'created_at',
        'updated_at'
    ];
    public $timestamps = true;
    protected $dates = [
        'deleted_at'
    ];
}

Finally, the DatabaseSeeder.php remains like this:

<?php

use App\Operator;
use App\Tour;
use App\Customer;
use App\CustomerTour;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        factory (Operator::class, 20)->create();
        $customers = factory (Customer::class, 300)->create();
        factory (Tour::class, 100)
        ->create()
            ->each(function ($tour) use ($customers)
                {
                    $tour->customers()
                        ->attach($customers
                            ->random(mt_rand(10, 40))
                            ->pluck('id')
                        );
                }
            );
    }
}

Everything works fine, except the field satisfaccion of the pivot table, which I filled in to NULL , instead of a randomElement , as I indicated in the factory.

Why does this happen? How can I fix it?

Thank you all.

    
asked by Chefito 04.12.2018 в 21:59
source

2 answers

1

Try the following way

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $satisfaccion = ['A', 'B', 'C'];
        factory (Operator::class, 20)->create();
        $customers = factory (Customer::class, 300)->create();
        factory (Tour::class, 100)
        ->create()
            ->each(function ($tour) use ($customers)
                {
                    $tour->customers()
                        ->attach($customers
                            ->random(mt_rand(10, 40))
                            ->pluck('id'), 
                             ['satisfaccion' => $satisfaccion[array_rand($satisfaccion)]]
                        );
                }
            );
    }
}

I think it's better to go directly to the attach the value of the satisfaction field

    
answered by 04.12.2018 / 23:00
source
0

I have found a solution, that I publish in case someone serves him. It is about filling the satisfaction field of the pivot table with NULL, and then, in the same seeder, using the Query Buider to generate random values in each record of the pivot table. The seeder code looks like this:

<?php

use App\Operator;
use App\Tour;
use App\Customer;
use App\CustomerTour;
use Illuminate\Database\Seeder;

use Illuminate\Support\Facades\DB;
use Faker\Generator as Faker;

class DatabaseSeeder extends Seeder
{
    public function run(Faker $faker)
    {
        factory (Operator::class, 20)->create();
        $customers = factory (Customer::class, 300)->create();
        factory (Tour::class, 100)
        ->create()
            ->each(function ($tour) use ($customers)
                {
                    $tour->customers()
                        ->attach($customers
                            ->random(mt_rand(10, 40))
                            ->pluck('id')
                        );
                }
            );
        $relaciones = DB::table('customer_tour')->get();
        foreach ($relaciones as $relacion) {
            $relacion->satisfaccion = $faker->randomElement(['A', 'B', 'C', 'D']);
            DB::table('customer_tour')
                ->where('id', $relacion->id)
                ->update(['satisfaccion' => $relacion->satisfaccion]);
        }
    }
}

I hope some of you find it as good a solution as it has been for me.

Greetings.

    
answered by 05.12.2018 в 13:36