Home > Software engineering >  Laravel issue when inserting many to many with pivot
Laravel issue when inserting many to many with pivot

Time:04-22

So I have a many to many relationship between attention and services / procedures A patient has many attentions, and an attention, belongs to a patient.

The issue comes when I seed attention procedures ( many to many relationship )

I transform the data according to laravel documentation, I'm using collections.

$procedures = Procedure::all()->mapWithKeys(function ($procedure,$key) {
            return [$procedure['id'] => [
                'price' => $procedure['price'],
                'price_USD' => $procedure['price_USD'],
                'amount' => rand(1, 10),
            ]];
        });

that should return me a value-key pair, where the array key is the procedure id.

but then when I try to attach procedures to attetions

$attention->procedures()->attach($procedures->random(rand(1,10))->all());

The migrations throws an error.

After debugging for a while, this is what ray throws

Procedures:

array:3 [▼
  0 => array:3 [▼
    "price" => 439.39
    "price_USD" => 17.87
    "amount" => 1
  ]
  1 => array:3 [▼
    "price" => 287.39
    "price_USD" => 11.69
    "amount" => 4
  ]
  2 => array:3 [▼
    "price" => 0.68
    "price_USD" => 0.03
    "amount" => 8
  ]
]

Query:

insert into
  `attention_procedure` (
    `amount`,
    `attention_id`,
    `price`,
    `price_USD`,
    `procedure_id`
  )
values
  (8, 1, 651.72, 26.51, 0),
  (10, 1, 403.18, 16.4, 1),
  (10, 1, 629.08, 25.59, 2),
  (10, 1, 930.84, 37.86, 3),
  (6, 1, 330.7, 13.45, 4),
  (5, 1, 629.53, 25.61, 5),
  (2, 1, 241.81, 9.84, 6),
  (10, 1, 354.68, 14.43, 7)

As you can see, it's trying to insert 0 as one of the procedure ids, which, doesn't exist.

How can I do so that the collection returns the procedure id as the array key?

CodePudding user response:

I think the mapWithKeys is ok, but it is the random which get only the values when you do:

->attach($procedures->random(rand(1,10))->all())

Try to get just some random records in the query and map them:

$procedures = Procedure::inRandomOrder()->limit(rand(1,10))->get()
    ->mapWithKeys(function ($procedure,$key) {             
        return [$procedure['id'] => [                 
            'price' => $procedure['price'],                 
            'price_USD' => $procedure['price_USD'],                 
            'amount' => rand(1, 10),             
        ]];         
    })
    ->toArray();

Then insert them:

$attention->procedures()->attach($procedures);

That way you will also be relieving the work to the database and also to php, since there will be fewer records to work on.

  • Related