'Laravel issue when inserting many to many with pivot

So I have a many-to-many relationship between attention and services/procedures.

A patient has many attentions, and attention belongs to a patient.

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

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 attentions.

$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?



Solution 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 porloscerros ?