Laravel 5.1:如何从多态关联的多对多表获取Dialogs?
解决Laravel 5.1中从Task关联获取Dialogs的问题
嘿,我来帮你梳理下这个关联问题,咱们一步步搞定它!首先得理清整个数据关系链:
Task和Npc是通过npcs_events_morphable表实现的多态多对多关联- 而
Dialog是和npcs_events_morphable表的记录通过dialog_npcseventsmorphable表做多对多关联的
所以要从 Task 拿到对应的 Dialogs,得通过 NpcsEventsMorphable 这个中间模型来串联关系,具体步骤如下:
1. 给Task模型加个关联到NpcsEventsMorphable
首先在 Task 模型里新增一个 morphMany 关联,用来获取当前Task对应的所有 NpcsEventsMorphable 记录——毕竟每个Task在中间表里可能对应多条记录(每条对应一个Npc):
class Task extends BaseModel { // 可以把新关联加入自动加载列表,按需选择要不要加 protected $with = ['npcs', 'npcsEventsMorphables']; public function npcs() { return $this->morphToMany('App\Npc', 'morphable', 'npcs_events_morphable'); } // 新增:获取当前Task对应的所有NpcsEventsMorphable记录 public function npcsEventsMorphables() { return $this->morphMany(NpcsEventsMorphable::class, 'morphable'); } }
2. 两种方式获取Dialogs
方式一:嵌套加载后提取
当你查询Task的时候,直接嵌套加载 npcsEventsMorphables.dialogs,然后把所有Dialog提取出来去重就行:
// 加载Task及其关联的NpcsEventsMorphable和Dialog $task = Task::with('npcsEventsMorphables.dialogs')->findOrFail(1); // 提取所有Dialog并去重(避免同一个Dialog被多个中间记录关联导致重复) $dialogs = $task->npcsEventsMorphables->flatMap(function ($morphable) { return $morphable->dialogs; })->unique('id');
方式二:加个访问器简化调用
如果你想更方便,直接用 $task->dialogs 就能拿到结果,可以在 Task 模型里加个访问器:
class Task extends BaseModel { // ... 其他已有代码 ... // 自定义访问器:自动返回关联的所有Dialogs public function getDialogsAttribute() { return $this->npcsEventsMorphables->flatMap(function ($morphable) { return $morphable->dialogs; })->unique('id'); } }
之后调用就超简单:
$task = Task::with('npcsEventsMorphables.dialogs')->findOrFail(1); $dialogs = $task->dialogs; // 直接拿到所有关联的Dialog
3. 确认已有关联的正确性
最后再检查下你已有的模型关联是否正确:
NpcsEventsMorphable模型的dialogs关联是对的:
class NpcsEventsMorphable extends BaseModel { protected $table = 'npcs_events_morphable'; protected $with = ['dialogs']; // 按需自动加载 public function dialogs() { return $this->belongsToMany(Dialog::class, 'dialog_npcseventsmorphable'); } }
- 如果需要从Dialog反向关联,
Dialog模型的关联可以改成这样(你之前的命名有点小问题,建议调整下):
class Dialog extends BaseModel { // 反向关联:获取当前Dialog对应的所有NpcsEventsMorphable记录 public function npcsEventsMorphables() { return $this->belongsToMany(NpcsEventsMorphable::class, 'dialog_npcseventsmorphable'); } }
这样操作后,你就能顺利从Task中获取到对应的Dialogs啦!
内容的提问来源于stack exchange,提问作者user3871
相关产品推荐
相关产品推荐

