Laravel 6 中的多态关系
Polymorphic relationships in Laravel 6
我有一个问题想自己解决几个小时,但我没有找到合适的解决方案 - 所以我需要你的综合脑力;)
我有一个游戏管理 Laravel 应用程序,它应该为以下实体提供通用消息系统:
- 字符
- 反派
每个用户可以拥有数量未知的角色和反派。
消息传递系统应该将每个实体相互连接起来,这意味着连接可以如下所示:
- 字符 --> 字符
- 人物 --> 反派
- 反派 --> 人物
- 小人 --> 小人
显然 Laravel 中的角色和恶棍是不同的 eloquent 模型。
为了更好地了解概览,我想开发一个消息收件箱,就像一个网络邮件程序,它显示来自所有角色和恶棍的所有消息。
我的想法是创建多态的一对多关系并向消息模型添加两个变形:
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 包含多态关系的必填字段,在迁移过程中使用以下方法创建:
$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。
有什么我弄错的想法吗?我不再见树不见林了。
非常感谢任何帮助或意见!
谢谢大家,
朱尔斯
好的,我想出了一个办法
默认情况下,当您访问 eloquent 关系作为属性时,关系的数据是延迟加载的。这意味着默认情况下不加载它。
我希望这表现得像一个普通的延迟加载,这意味着当我访问 属性 时它会自动加载关系并让我访问相关模型的属性。好像不是这样。
一旦我将以下行添加到我的 "Message" eloquent 模型中,我上面所做的一切都完美无缺:
protected $with = ['sender', 'recipient'];
模型的受保护 "with" 属性 告诉 eloquent 在查询数据时它应该急切加载(而不是延迟加载)哪些关系。添加发件人和收件人后,我所有的相关数据都默认加载 - 不再懒惰 - 但它已加载。
在我看来,此行为可能是 Laravel 6.7.0 中的错误,我将在 GitHub 存储库中报告此问题。
可以在此处找到有关预先加载的更多信息:https://laravel.com/docs/6.x/eloquent-relationships#eager-loading
希望对您有所帮助。
我有一个问题想自己解决几个小时,但我没有找到合适的解决方案 - 所以我需要你的综合脑力;)
我有一个游戏管理 Laravel 应用程序,它应该为以下实体提供通用消息系统:
- 字符
- 反派
每个用户可以拥有数量未知的角色和反派。
消息传递系统应该将每个实体相互连接起来,这意味着连接可以如下所示:
- 字符 --> 字符
- 人物 --> 反派
- 反派 --> 人物
- 小人 --> 小人
显然 Laravel 中的角色和恶棍是不同的 eloquent 模型。
为了更好地了解概览,我想开发一个消息收件箱,就像一个网络邮件程序,它显示来自所有角色和恶棍的所有消息。
我的想法是创建多态的一对多关系并向消息模型添加两个变形:
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 包含多态关系的必填字段,在迁移过程中使用以下方法创建:
$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。
有什么我弄错的想法吗?我不再见树不见林了。
非常感谢任何帮助或意见!
谢谢大家, 朱尔斯
好的,我想出了一个办法
默认情况下,当您访问 eloquent 关系作为属性时,关系的数据是延迟加载的。这意味着默认情况下不加载它。
我希望这表现得像一个普通的延迟加载,这意味着当我访问 属性 时它会自动加载关系并让我访问相关模型的属性。好像不是这样。
一旦我将以下行添加到我的 "Message" eloquent 模型中,我上面所做的一切都完美无缺:
protected $with = ['sender', 'recipient'];
模型的受保护 "with" 属性 告诉 eloquent 在查询数据时它应该急切加载(而不是延迟加载)哪些关系。添加发件人和收件人后,我所有的相关数据都默认加载 - 不再懒惰 - 但它已加载。
在我看来,此行为可能是 Laravel 6.7.0 中的错误,我将在 GitHub 存储库中报告此问题。
可以在此处找到有关预先加载的更多信息:https://laravel.com/docs/6.x/eloquent-relationships#eager-loading
希望对您有所帮助。