laravel icon indicating copy to clipboard operation
laravel copied to clipboard

Attributes from related belongsTo model

Open bbprojectnet opened this issue 3 years ago • 6 comments

It is possible? For now, when i create a resource, related model is saved, but related columns in main resource is not filled at all.

My guess is that the assumptions are made here that the relationship will always be hasOne, so, the related model is written after the main one, am i wrong?

Any change to add support also for belongsTo? or any temporary solution for that case? ;)

bbprojectnet avatar Jan 12 '22 11:01 bbprojectnet

Hi. Sorry, not really clear on what the scenario is. Can you give more detail?

lindyhopchris avatar Jan 12 '22 19:01 lindyhopchris

Hi, yes, sure.

I'm talking about this feature: https://laraveljsonapi.io/docs/1.0/schemas/attributes.html#attributes-from-related-models which works with hasOne relation, but not with belongsTo (not for create requests).

bbprojectnet avatar Jan 13 '22 07:01 bbprojectnet

Ah right, I understand now!

Yeah this only works currently with hasOne because Eloquent has the withDefault() for that relationship, so we can use that to create the related model if it doesn't already exist. There isn't a similar capability in Eloquent for the belongsTo relationship.

In theory I'm guessing we could support it, we would just need some sort of callback registered on the field so that we know how to create a new model if there wasn't an existing one to fill.

lindyhopchris avatar Jan 13 '22 07:01 lindyhopchris

Eloquent also has withDefault for belongsTo :) It almost works with laravel json api, related model is created, but without foreign key value i main resource.

For now i workaround this with that trick:

Main resource schema:

Str::make('age')
	->fillUsing(static function (Declaration $declaration, string $column, $value) {
		$declaration->patientData->setAttribute('age', $value);
	}),

Main resource creating event observer:

$declaration->patientData->save();
$declaration->patientData()->associate($declaration->patientData);

bbprojectnet avatar Jan 13 '22 07:01 bbprojectnet

Ah ok then this'll be a bug, as it should work with belongs to as well then.

lindyhopchris avatar Jan 13 '22 09:01 lindyhopchris

So have looked into this, and it's pretty complicated.

The withDefault() behaviour doesn't work as I'd expect for a belongs-to relation. The docs use the example of Post->user(), but given this:

$post = new Post([
    'content' => '...',
    'slug' => 'hello-world',
    'title' => 'Hello World',
]);

$post->save();

$post->user->fill([
    'name' => 'John',
    'email' => '[email protected]',
])->save();

$this->assertSame($post->user->getKey(), $post->user_id);

The post doesn't have user_id set on it so the assertion fails. I.e. the default user hasn't actually been associated back to the post, which is why they then loose the association.

So not quite sure how to get this working??? Any ideas appreciated.

lindyhopchris avatar Feb 20 '22 17:02 lindyhopchris