I got two models in Laravel: Label
class Label extends \Eloquent
{
protected $fillable = [
'channel_id',
'name',
'color',
];
public function channel()
{
return $this->belongsTo('App\Channel');
}
}
And Channel
class Channel extends \Eloquent
{
protected $fillable = [
'name',
];
public function labels()
{
return $this->hasMany('App\Label');
}
}
Now when a label is deleted, I want to make sure, the label belongs to the channel.
This works pretty good, as it even is atomic, so the row will just be deleted, if the label really belongs to the channel.
LabelController:
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$channel = $this->getChannel();
Label::where('id', $id)
->where('channel_id', $channel->id)
->delete();
return back();
}
And my question is now: How to build that with Eloquent, so it is elegant? Something like:
$channel->labels()->destroy($id);
But there is no destroy function on the relation.
Update:
I managed to achieve something in the right direction:
$channel->labels()->find($id)->delete();
This deletes the label with $id BUT just if the label has the right channel_id assigned. If not, I get the following error, which I could catch and handle:
FatalThrowableError (E_ERROR) Call to a member function delete() on null
Still, as Apache is threaded, there could be the case that another thread changes the channel_id after I read it. So the only way besides my query is to run a transaction?
$channel = $this->getChannel();
and also check in the query if the channel_id matches->where('channel_id', $channel->id)
? Shouldn't the first statement make the second one obsolete? – Thatcher$channel->labels()->find($id)->delete();
but it will delete only 1 channel? What about just$channel->labels()->delete();
? – Mercaptide$channel->labels()->find($id)->delete();
it will delete the Label if it is connected to channel. Think Laravel does something like select * from labels where channel_id = Channel->id and then find($id) on this result. If I force the destroy method with an $id that has a different channel I get the exception above. – Hames$channel->labels()->delete();
will not delete channel, it will delete all labels related to this channel – Mercaptide