#Idea: BelongsTo Simplification

11 messages · Page 1 of 1 (latest)

hasty raptor
#

Currently I have a relation between a location and a state. So a location belongs to one state and a state can have many locations.

I have set up the relation correctly:

class Location extends Model
{
    public function state(): BelongsTo
    {
        return $this->belongsTo(State::class);
    }
}

Of course the location model has a foreignId column named state_id and all tables and columns follow the name conventions.

When I now want to create a relation I have two options. Option one is to use the "official" way with associate:

$state = State::where(['short'=>'AUT'])->first();
$location = new Location();
$location->name = 'Vienna';
$location->state()->associate($state);
$location->save();

There is also the more basic way (which is not recommended but still working):

$state = State::where(['short'=>'AUT'])->first();
$location = new Location();
$location->name = 'Vienna';
$location->state_id = $state->id;
$location->save();

Wouldn't it be much easier to make this more straightforward and let Laravel automatically detect if an association is needed?
It would be much easier if I could do this:

$state = State::where(['short'=>'AUT'])->first();
$location = new Location();
$location->name = 'Vienna';
$location->state = $state;
$location->save();

but this method is not working and will result in an error saying that column state does not exist.
What do you think: Is this something which would be useful? Should I create a feature request?

stone crown
#

The column state does not exist is a MySQL error. So is that column in your schema?

hasty raptor
#

Of course not. The schema contains state_id as it should be. The point is, that the state is a relationship and I think that Laravel could detect this when you do $location->state = $state; and internally make a $location->state()->associate($state); automatically. But I want to clarify, if my thinking is right and if this would also be an improvement to others before I make a official request.

fathom bronze
#

Not sure I understand the problem, but there are a couple of other options..1st if you have the relation the other way around state hasMany locations then you 'could do'

$state = State::where(['short' => 'AUT'])->first();

$location = $state->locations()->create([
    'name' => 'Vienna',
]);

or the more explicit way (I find more common)

$state = State::where(['short' => 'AUT'])->first();

$location = locations::create([
    'name' => 'Vienna',
'state_id' => $state->id,
]);

you could of course pluck the state id or select only the id if you really wanted to, but assuming this would come from the frontend then ideally it'd be validated in a form request so then it's even shorter...

$location = Location::create($request->validated());

Sorry if I've missed your point but some options anyway 🙂

hasty raptor
#

Thanks @fathom bronze for the explanations. Yes that are of course other options you can link the two models together. I just wanted to ask if it would make sense to implement a new feature which support the method I described. So instead of

$location->state()->assosciate($state);

a shorter version COULD be:

$location->state = $state;

So it's just a short form of the upper version. Currently Laravel does not support it, but it would be nice for me.
The question is if I'm the only one, or if others would also benefit from a function like that.

fathom bronze
#

Ah ok, for me I don't see the need but others may agree/disagree of course - there is the attach() method when using a pivots on many to many so I guess the logic would be similar (e.g. to resolve the ids using the naming conventions) hmm

#

Looked back at the docs on the save method for this as it's quite interesting - this kind of does what you suggest already to be fair it's just a change in the naming

$post->comments()->save($comment);

I don't see anything to suggest it wouldn't work on a belongsTo but I haven't tried it 🙂

hasty raptor
#

Seems that my way of thinking is not very common 😄 .
So I will stick with the official documented options.
Thanks for you help.
PS: I want to tag this it as solved, but there is no tag.

fathom bronze
dusk cradle
# fathom bronze FYI from the first message in help..

A recent restructure had the solved tag removed and afaik it's now at the limit of tags allowed in this channel, so can't be added either. Guess the idea is to not have a solved tag at all anymore. I'll remove that from the pinned post. Up to crew/staff what they want to do further

#

Welp, nevermind, I can't edit that post anymore 😬