【问题标题】:SoftDeletes on model breaks dynamic properties模型上的 SoftDeletes 破坏动态属性
【发布时间】:2016-05-31 23:48:39
【问题描述】:

TLDR:当SoftDeletes 特征包含在我的父模型中时,我不再将父模型的软删除实例作为子模型的动态属性。如何做到这一点?


我已经定义了几个基本模型,如下所示:

<?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");
    }
}

在我的控制器中,我想列出待处理的帖子,所以我这样做:

<?php
namespace App\Controllers;

use App\Post;

class PostController extends Controller
{

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

最后,在我看来:

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

这导致抛出异常,“尝试获取非对象的属性”,行号对应于我尝试为已软删除的用户输出 $post-&gt;user-&gt;name 的位置。

如何让这些动态属性包含软删除的项目?

【问题讨论】:

    标签: php laravel laravel-5 eloquent soft-delete


    【解决方案1】:

    显然相关用户模型已被软删除,这就是相关用户未加载的原因。

    在下面的代码中定义关系,无论用户是否被软删除,您都可以随时获取用户:

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

    【讨论】:

      【解决方案2】:

      如果你这样做很遗憾

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

      您将无法再使用对用户关系的动态访问,因为动态访问期望关系方法返回BelongsTo 实例,该实例由Eloquent 类的belongsTo 方法返回。但是withTrashed 返回Builder 实例。

      编辑

      我错了,感谢 @patricius 被引导到正确的道路上(在 cmets 中)。

      【讨论】:

      • 这是不正确的。 $this-&gt;belongsTo("App\User") 将返回一个 BelongsTo 对象。然后,当您在 BelongsTo 对象上调用 withTrashed() 时,它会落入扩展 Relation 对象上的 __call() 方法中。 __call() 方法将在底层 Builder 对象上调用 withTrashed(),但它会将 BelongsTo 对象返回给原始调用者。因此,$this-&gt;belongsTo("App\User")-&gt;withTrashed(); 将返回一个 BelongsTo 对象。
      • @patricus,感谢您的解释,我现在不知道该怎么办。应该编辑/删除我的答案还是保持原样?
      • 由你决定。尽管评论提供了有用的信息,但有些人没有参加 cmets,只是阅读了答案。您可以删除您的答案,也可以对其进行编辑以显示它不正确,并且您只是因为评论中的有用信息而保留它。如果您决定保留该信息,我们非常欢迎您将这些信息添加到您的答案中。
      猜你喜欢
      • 2012-10-03
      • 2017-10-03
      • 2014-11-19
      • 1970-01-01
      • 2023-03-09
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      相关资源
      最近更新 更多