TryHardz
TryHardz

Reputation: 159

How can I use soft deleted with relation

I use eloquent with soft delete .I'm getting error because of my query still select data that already use softdelete here is my model

User Model

class User extends Authenticatable
{
    use Notifiable, HasRoles, SoftDeletes;
    protected $guard_name = 'web';
    protected $fillable = [
        'username', 'password'
    ];
    protected $dates = ['deleted_at'];

}

for example I've 100 user and I deleted 1 user with softdelete . then I try to

$a = User::all();
dd($a);

I get 99 user . It works! but after I use it relation It doest work here what I do

This is my Parent table and Model

table

 |id|user_id|parent_id|

Note : user_id and parent_id are FK in user.id table

class Parent extends Model
{
    protected $table = 'parent';
    public function user()
    {
        return $this->belongsTo('App\User');
    }

}


$getParent = Parent::with('user')->get();

when I dd($getParent); why I still get null data from user_id that I already use soft deleted ?

UPDATE model User : after I put whereNull I still getting user that I alredy soft deleted

public function user()
{
    return $this->belongsTo('App\User')->whereNull('users.deleted_at');
}

Upvotes: 1

Views: 8108

Answers (3)

Fatih
Fatih

Reputation: 53

https://laravel.com/docs/5.7/eloquent#querying-soft-deleted-models

...
    public function customerAddress()
    {
        return $this->hasOne(Addresses::class, "id", "id_address")->withTrashed();
    }
...

Upvotes: 2

Christoffer
Christoffer

Reputation: 7777

Ok, here's what I think is going on...

With soft delete the ondelete event doesn't work (meaning that related models is not deleted). I'm not sure if that changed in later versions of Laravel, but I don't think so. Also deleting User would still not affect the parent model, since you haven't defined the relationship between User and Parent (in the User model), only between Parent and User.

Try defining the relationship in User and then override the boot() function, that sits in the Model class. (This is untested code, but something like this should do the job)

class User extends Authenticatable
{
    use Notifiable, HasRoles, SoftDeletes;
    protected $guard_name = 'web';
    protected $fillable = [
        'username', 'password'
    ];
    protected $dates = ['deleted_at'];

    // Override Model boot function
    protected static function boot()
    {
        parent::boot();

        static::deleting(function ($users) {
            foreach ($users->parents()->get() as $parent) {
                $parent->delete();
            }
        });
    }

    // Define relationship with parent model
    public function parents()
    {
        $this->hasMany('App\Parent');
    }
}

Upvotes: 1

M. A. Pervez
M. A. Pervez

Reputation: 25

You can put a constraint on the Eager Load:

public function groups()
{

    return $this
    ->belongsToMany('Group')
    ->whereNull('group_user.deleted_at') // Table `group_user` has column `deleted_at`
    ->withTimestamps(); // Table `group_user` has columns: `created_at`, `updated_at`

}

Instead of HARD deleting the relationship using:

User::find(1)->groups()->detach();

You should use something like this to SOFT delete instead:

DB::table('group_user')
->where('user_id', $user_id)
->where('group_id', $group_id)
->update(array('deleted_at' => DB::raw('NOW()')));

Upvotes: 0

Related Questions