【问题标题】:Polymorphic relationships in Laravel 6Laravel 6 中的多态关系
【发布时间】:2019-12-12 22:31:30
【问题描述】:

我有一个问题,我试图自己解决几个小时,但我找不到合适的解决方案 - 所以我需要你的综合脑力;)

我有一个游戏管理 Laravel 应用程序,它应该为以下实体提供通用消息传递系统:

  • 字符
  • 恶棍

每个用户可以拥有未知数量的角色和反派。

消息系统应该将每个实体相互连接,这意味着连接可能如下:

  • 字符 --> 字符
  • 角色 --> 恶棍
  • 恶棍 --> 人物
  • 恶棍 --> 恶棍

显然 Characters 和 Villains 在 Laravel 中是不同的雄辩模型。

为了获得更好的概览,我想开发一个消息收件箱,例如网络邮件程序,它显示来自所有角色和恶棍的所有消息。

我的想法是创建多态的一对多关系并在消息模型中添加两​​个变形:

public function sender ()
{
    return $this->morphTo();
}

public function recipient ()
{
    return $this->morphTo();
}

虽然角色和反派模型也有两个变形,但每个变形:

public function receivedMessages()
{
    return $this->morphMany('App\Models\Message', 'recipient');
}

public function sentMessages()
{
    return $this->morphMany('App\Models\Message', 'sender');
}

我的消息表包含多态关系的必填字段,在迁移期间使用以下方法创建:

$table->morphs('sender');
$table->morphs('recipient');

所以在我的想法中,我可以简单地查询特定用户的所有消息,其中包括所有角色和所有恶棍消息。从该消息列表中,我应该能够检索到各个角色和恶棍信息,就像这样:

@foreach($receivedMessages as $message)

    @if($message->sender() instanceof \App\Models\Character)
        // Do something character specific
    @endif

    @if($message->sender() instanceof \App\Models\Villain)
        // Do something villain specific
    @endif
@endforeach

不幸的是,我似乎无法从消息对象中检索到角色和反派信息。如果我只是使用:

$message->sender

结果为 null。如果我使用:

$message->sender()

结果不为空,但我仍然无法检索角色或反派实例的属性,例如:

$message->sender()->name

总是会抛出 BadMethodCallException。

有什么想法我弄错了吗?我不再只见我害怕的树木。

非常感谢任何帮助或输入!

谢谢大家, 朱尔斯

【问题讨论】:

  • 你创建的字段是否按照 laravel 约定命名?
  • 嗨@AlbertoSinigaglia,是的,我确实做到了。我将字段 senderable_id 和 _type 以及 recipientable_id 和 _type 添加到我的消息表中,并相应地播种它们以进行测试。

标签: php laravel eloquent polymorphism entity-relationship


【解决方案1】:

好的,我想出了一个解决方案。

默认情况下,当您将 eloquent 关系作为属性访问时,关系的数据是延迟加载的。这意味着默认情况下不加载它。

我希望它的行为类似于常见的延迟加载,这意味着当我访问属性时,它会自动加载关系并让我访问相关模型的属性。好像不是这样的。

一旦我将以下行添加到我的“消息”雄辩模型中,我上面所做的一切都完美无缺:

protected $with = ['sender', 'recipient'];

模型的受保护“with”属性告诉 eloquent 在查询数据时应该预先加载(而不是延迟加载)哪些关系。添加发件人和收件人后,我的所有相关数据都默认加载 - 不再懒惰 - 但已加载。

在我看来,这种行为可能是 Laravel 6.7.0 中的一个错误,我将在 GitHub 存储库中报告此问题。

更多关于预加载的信息可以在这里找到:https://laravel.com/docs/6.x/eloquent-relationships#eager-loading

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 2020-06-13
    • 2019-01-22
    • 2019-02-02
    • 2016-08-30
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多