#Update or create (associate) BelongsTo relation

1 messages · Page 1 of 1 (latest)

ashen breach
#

Hi. I am trying to update an existing or create a new associated model relation (Contact) in my controller, but this code is bloated:

        if ($model->contact) {
            $model->contact->update($request->validated());
        } else {
            $model->contact()->associate(
                Contact::create($request->validated())
            )->save();

then I tried with updateOrCreate(), but that would not associate the created model:

        $model->contact()->updateOrCreate([], $request->validated());
        $model->save();

so I have written the following Builder macro:

        /**
         * Update an existing BelongsTo relation or associate a new one.
         */
        Builder::macro('updateOrAssociate', function (string $relation, array $attributes): void {
            $relatedModel = $this->getModel()->$relation()->updateOrCreate([], $attributes);
            if (! $this->getModel()->$relation()->exists()) {
                $this->getModel()->$relation()->associate($relatedModel)->save();
            }
        });

and using it in my controller:

$model->updateOrAssociate('contact', $request->validated());

that works, but I don't think this is quite clean, as it is only meant to be used for BelongsTo relations, but defined on Builder. Is there a better way of doing it, some Eloquent built-in helper method?

silent parrot
#

I also assumed that the foreign key would be included by default in that scenario. Weird.

#

A simpler solution would be to include the foreign key in the validated data. If it's not included in the request, you can merge it in before validating.

silent parrot
#

Wait, it does work as I expected. So in your case $model belongs to a Contact? I thought it was the other way around.