检索多态模型实例

Retrieve polymorphic model instances

使用 Laravel 5.1,我正在尝试创建一个动态 table,我可以在其中将多个项目类型与 module 相关联。我使用 Polymorphic table 并将每个模块的 morphable_idsmorphable_types 设置为这样:

id  module_id morphable_id morphable_type
1       1          1       App/Enemy
2       2          2       App/Enemy
3       3          1       App/Item

我通过关联 tasks 获取我的模块,也就是 modules 急切加载任务。当我从 API 调用深入了解我的任务并检查 module_items 时,它显示文字 morphable_id/morphable_type 而不是 App\EnemyApp\Item 个我正在寻找的实例:

more task obj properties...
"module":{
   "id" : 1
   "module_items":[
      {
        "id": 3,
        "module_id": "3",
        "morphable_id": "1",
        "morphable_type": "App/Item"
      }
   ]
 }

所以我的问题是,我如何实际检索多态模型实例(例如,我检索模块 1 的 ID 1App\Item)?

这里有更多信息:

型号:

任务:加载模块

class Task extends Model
{

    protected $with = ['module'];


    public function module()
    {
        return $this->belongsTo(Module::class);
    }
}

模块

class Module extends Model
{
    protected $with = ['module_items'];

    public function task()
    {
        return $this->belongsTo(Task::class);
    }

    public function module_items()
    {
        return $this->hasMany(ModuleItem::class);
    }
}

多态ModuleItem模型

class ModuleItem extends Model
{
    public function typeable()
    {
        return $this->morphTo();
    }

    public function module()
    {
        return $this->belongsTo(Module::class);
    }
}

项目的多态关系

class Item extends Model
{
    public function module_item_types()
    {
        return $this->morphMany('App\ModuleItem', 'typeable');
    }
}

敌人的多态关系

class Enemy extends Model
{
    public function module_item_types()
    {
        return $this->morphMany('App\ModuleItem', 'typeable');
    }
}

看看Illuminate\Database\Eloquent@morphMany:

/**
 * Define a polymorphic one-to-many relationship.
 *
 * @param  string  $related
 * @param  string  $name
 * @param  string  $type
 * @param  string  $id
 * @param  string  $localKey
 * @return \Illuminate\Database\Eloquent\Relations\MorphMany
 */
public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
{
    $instance = new $related;

    // Here we will gather up the morph type and ID for the relationship so that we
    // can properly query the intermediate table of a relation. Finally, we will
    // get the table and create the relationship instances for the developers.
    list($type, $id) = $this->getMorphs($name, $type, $id);

    $table = $instance->getTable();

    $localKey = $localKey ?: $this->getKeyName();

    return new MorphMany($instance->newQuery(), $this, $table.'.'.$type, $table.'.'.$id, $localKey);
}

如果您通过 Illuminate\Database\Eloquent@getMorphs 跟随兔子洞,您将看到如果 $type 为空,则数据库 table 名称是通过 $name 参数推断出来的。您的列名被推断为 typeable_idtypeable_type 而不是 morphable_idmorphable_type.

修复后,您应该能够访问 ModuleItem 的类型,例如 $module_item->typeable(或您将关系重命名为的任何内容)。如果您想预先加载类型实例,您将更新 ModuleItem:

class ModuleItem extends Model
{
    protected $with = ['typeable'];

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

    public function module()
    {
        return $this->belongsTo(Module::class);
    }
}