Laravel双向多态多对多关联:获取关联模板对象的PHP代码
Laravel 双向多态关联实现:从实例模型获取对应模板模型
你的场景属于双向多态关联(中间表同时存储两端模型的类型和ID),可以通过以下代码实现需求:
1. 创建中间表模型 TemplateRegistry
这个模型作为关联枢纽,连接实例模型与模板模型:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphTo; class TemplateRegistry extends Model { protected $table = 'template_registry'; public $timestamps = false; // 若中间表无created_at/updated_at字段,开启此行 // 关联到实例模型(Field/Event等) public function instance(): MorphTo { return $this->morphTo(__FUNCTION__, 'instance_type', 'instance_id'); } // 关联到模板模型(TemplateField/TemplateEvent等) public function template(): MorphTo { return $this->morphTo(__FUNCTION__, 'template_type', 'template_id'); } }
2. 在实例模型(以Field为例)中定义关联与访问器
通过MorphOne关联到中间表,再用访问器直接返回模板对象:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphOne; class Field extends Model { // 关联到中间表 public function templateRelation(): MorphOne { return $this->morphOne(TemplateRegistry::class, 'instance') ->with('template'); // 预加载模板模型,避免N+1查询 } // 自定义访问器,实现$field->template直接获取模板对象 public function getTemplateAttribute() { return $this->templateRelation->template ?? null; } }
Event模型可直接复用上述逻辑,仅需保证类名正确。
3. 模板模型(以TemplateField为例)(可选)
若需从模板模型反向关联到实例模型,可添加以下代码:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphOne; class TemplateField extends Model { public function instanceRelation(): MorphOne { return $this->morphOne(TemplateRegistry::class, 'template') ->with('instance'); } public function getInstanceAttribute() { return $this->instanceRelation->instance ?? null; } }
使用方式
现在可以直接通过实例模型获取对应的模板对象:
$field = \App\Models\Field::find(1); $template = $field->template; // 返回TemplateField实例或null
内容的提问来源于stack exchange,提问作者vbulash
相关产品推荐
相关产品推荐

