Laravel 5中如何在子模型类中添加$with/$appends字段

5

我有几个模型共享某些通用功能(由于它们的多态性),我希望将它们提取到一个ResourceContentModel类(或甚至是特征)中。

ResourceContentModel类将扩展eloquent Model类,然后我的各个模型将扩展ResourceContentModel。

我的问题在于模型字段,如$with、$appends和$touches。如果我在ResourceContentModel中使用它们来实现任何通用功能,那么当我在子模型类中重新定义它们时,它会覆盖我在父类中设置的值。

寻找一些干净的方法来解决这个问题?

例如:

class ResourceContentModel extends Model
{
    protected $with = ['resource']
    protected $appends = ['visibility']

    public function resource()
    {
        return $this->morphOne(Resource::class, 'content');
    }

    public function getVisibilityAttribute()
    {
        return $this->resource->getPermissionScope(Permission::RESOURCE_VIEW);
    }
}

class Photo extends ResourceContentModel
{
    protected $with = ['someRelationship']
    protected $appends = ['some_other_property']

    THESE ARE A PROBLEM AS I LOSE THE VALUES IN ResourceContentModel
}

我希望以简洁的方式完成这个任务,使得子类不会因为我在继承结构中增加了一个额外的类来收集公共代码而过度改变。


对于$appends,请查看https://laracasts.com/discuss/channels/general-discussion/define-model-attributes-in-trait/replies/50522;对于`$with`,您可以尝试查看https://laravel.com/docs/5.6/eloquent#global-scopes。 - ctf0
2个回答

1

没有想法这是否会成功...

class Photo extends ResourceContentModel
{
    public function __construct($attributes = [])
    {
        parent::__construct($attributes);
        $this->with = array_merge(['someRelationship'], parent::$this->with);
    }
}

或者在ResourceContentModel上添加一个方法来访问该属性。
class ResourceContentModel extends Model
{
    public function getParentWith()
    {
        return $this->with;
    }
}

那么

class Photo extends ResourceContentModel
{
    public function __construct($attributes = [])
    {
        parent::__construct($attributes);
        $this->with = array_merge(['someRelationship'], parent::getParentWith());
    }
}

编辑

在第三个代码片段的构造函数中,

$this->with = array_merge(['someRelationship'], parent->getParentWith());

需要更改为

$this->with = array_merge(['someRelationship'], parent::getParentWith());


谢谢,我喜欢这个,我在那里使用了你的第一个想法,尽管我将自定义构造函数放在ResourceContentModel类中,这意味着子类都可以像正常情况下设置$with和$appends一样。作为受保护而不是私有字段,重写的值在基类中是可访问的,所以我可以将它们与共同的值合并。非常整洁... - madz
很高兴听到这个消息,打出 parent::$this->with 看起来有点奇怪。但我很高兴它能够工作,也许将来我自己也会用到它 =) - user320487
是的,我对那个特定的语法不太确定(我不知道你能做到那样),但是因为我把你建议的逻辑放在父类构造函数中,所以我只需要引用 $this->with。 - madz

0

我发现在PHP 7.1中使用parent::$this->appends会导致PHP错误。

这个方法对我有用:

父模型:

<?php

use Illuminate\Database\Eloquent\Model as BaseModel;

class Model extends BaseModel
{
    public function __construct($attributes = [])
    {
        parent::__construct($attributes);

        $this->append([
            'everyChildModelAppendsThis',
        ]);
    }
}

子模型:

<?php

class ChildModel extends Model
{
    protected $appends = [
        'childModelStuff',
    ];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接