Search code examples
phplaravellaravel-5eloquentsoft-delete

SoftDeletes on model breaks dynamic properties


TLDR: When the SoftDeletes trait is included in my parent model, I no longer get soft deleted instances of the parent model as a dynamic property of the child. How can this be done?


I have defined a couple of basic models, like this:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Builder;

class User extends Model
{
    use SoftDeletes;

    public function posts()
    {
        return $this->hasMany("App\Post");
    }
}

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo("App\User");
    }

    public function scopePending(Builder $query)
    {
        return $query->whereNull("pending");
    }
}

In my controller, I want to list pending posts, so I do this:

<?php
namespace App\Controllers;

use App\Post;

class PostController extends Controller
{

    public function index()
    {
        $posts = Post::pending()->get();
        return view("post.index", ["pending"=>$posts]);
    }
}

And finally, in my view:

@foreach($pending as $post)
    {{ $post->title }}<br/>
    {{ $post->user->name }}<br/>
@endforeach

This results in an exception being thrown, "Trying to get property of non-object" with the line number corresponding to where I try to output $post->user->name for users which have been soft deleted.

How can I have these dynamic properties include soft deleted items?


Solution

  • Apparently the related user model has been soft-deleted, that's why the related user is not loaded.

    Define the relation like in the code below and you'll be always able to fetch a user regardless if they have been soft-deleted or not:

    public function user()
    {
        return $this->belongsTo("App\User")->withTrashed();
    }