Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete single (many-) rows from one-to-many relations in Laravel 5.5

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?

like image 650
andi79h Avatar asked Dec 08 '17 16:12

andi79h


People also ask

How do I delete a single record in laravel?

To do so follow the below steps one by one: Step 1: Create Controller UserController by executing this command. Step 2: We can delete records in two ways. Second Method: The second way is to delete using the Laravel delete Function and User Model (Easy one).

What is Cascade delete in laravel?

Laravel Soft Cascade is a package that makes it easy to perform soft cascade deletes and restores on related models using soft deleting.

How do I remove all records from a table in laravel eloquent?

In the first example, we are going to use the truncate() function, which is used to delete all the records. In the second example, we will delete records on the basis of the id. So we will specify some id and use the delete() function to delete all the records of that particular id.


1 Answers

If you want to delete related items of your model but not model itself you can do like this:

$channel->labels()->delete(); It will delete all labels related to the channel.

If you want to delete just some of labels you can use where()

$channel->labels()->where('id',1)->delete();

Also if your relation is many to many it will delete from third table too.

like image 132
Makashov Nurbol Avatar answered Sep 21 '22 21:09

Makashov Nurbol