首页 > 解决方案 > Laravel 5.7 - 使用 morphMany 关系和自定义属性获取器的渴望加载

问题描述

所以我有以下模型:

class TemplateEntity extends Model {
    protected $table = "TemplateEntities";

    const UPDATED_AT = null;
    const CREATED_AT = null;

    public function element() {
        return $this->morphTo("element", "entity_type", "id_Entity");
    }

    public function getEntityTypeAttribute($entity_type) {
        return 'App\\' . $entity_type;
    }
}

class Template extends Model {
    protected $table = "Template";

    const UPDATED_AT = null;
    const CREATED_AT = null;

    public function entities() {
        return $this->hasMany("App\TemplateEntity", "id_Template");
    }
}

class TemplateEntity extends Model {
    protected $table = "TemplateEntities";

    const UPDATED_AT = null;
    const CREATED_AT = null;

    public function element() {
        return $this->morphTo("element", "entity_type", "id_Entity");
    }

    public function getEntityTypeAttribute($entity_type) {
        return 'App\\' . $entity_type;
    }
}

我想使用 Eloquent ORM 的 ::with() 方法预先加载模板实体元素,但是每当我这样做时,我都会收到错误消息:

//$template_id is defined as a controller param
$template = Template::with("entities", "entities.element")->where("id", "=", $template_id)->get()

"Class 'App\' not found"

我做了一些调试,当我在 TemplateEntity 的 GetEntityTypeAttribute() 方法中回显 $entity_type 时,我得到一个空值。但是,如果我不使用预加载,我的模型通常可以正常工作,但如果可能的话,我想将它添加到我的应用程序中以提高效率。

你们能提供的任何帮助都会有所帮助!

编辑:修正了一个错字,应该是 Template::with 而不是 $template::with

标签: phplaraveleager-loading

解决方案


部分问题可能是该变量中的空白类。建议您在调用时使用类名get()。所以\App\Template::代替$template::.

另一个有帮助的项目可能是你调用关系的急切负荷的方式。也许尝试通过函数调用。这可能对您更有效:

 \App\Template::with(['entities' => function($query){
        $query->with('element');
    }])->get();

访问器函数可能会干扰 Laravel 变形函数。我意识到您想在数据库中使用类的缩写名称。要在不使用 getter(和全局)的情况下做到这一点,我建议使用 morphMap。

AppServiceProvider方法里面boot()

  \Illuminate\Database\Eloquent\Relations\Relation::morphMap([
        'MyTemplate' => \App\MyTemplate::class,  
        'Section' => \App\Section::class,  
         // etc.        
    ]);

这将允许您仅将“部分”添加到数据库并从您的类中删除访问器函数。


推荐阅读