Search code examples
phplaraveleloquentrelationshiphas-many

Laravel updateOrCreate with hasMany relationship


I have users that can have multiple parameters. These are called for example user_param_1, user_param_2, ..., user_param_n. This is dynamic. It is a separate table user_parameters, which stores id, user_id, name and value. The relationship is a belongsTo and hasMany between Users and UserParameters. The problem is:

When editing, I want to keep it dynamically and if the user has an user_param_n+1, it should be created. But I already have problems to write the condition for the existing parameters.

I create myself an userParameters array, which contains from the $request variable only the necessary parameters. The array looks like this:

[
  0 => [
    "name" => "par1"
    "value" => "var1"
  ]
  1 => [
    "name" => "par2"
    "value" => "var2"
  ]
  2 => [
    "name" => "par3"
    "value" => "var3"
  ]
]

Then I want to save it. My controller knows the user, so I can access to $user->id.

foreach ($userParameters as $userParameter) {
        $user->parameters()->updateOrCreate(['id' => $user->parameters->id, 'user_id' => $user->id], $userParameter);
}

The issue is, that $user->parameters is an array of eloquent models. The condition is wrong. I can't access id directly. But how I can solve it? I need something like "['id' => [IF-DATABASE-ID-EXISTS-IN-ARRAY-$user-parameters]"... but how in an eloquent way?

Thanks in advance!

Best regards


Solution

  • I think you need to get the existing parameter using user_id and parameter_name cuz it's the uniqueness of that parameter row, if there is no parameter with this name it will create it with user_id & parameter_name and parameter_value passed to updateOrCreate function

    foreach ($parameters_from_request as $parameter) {
            $user->parameters()
                    ->updateOrCreate(
                     [
                     'name' => $parameter['name'] ,
                     'user_id' => $user->id
                     ],[
                       'name' => $parameter['name'],
                       'value'=> $parameter['value']
                       ]);
    }