0

我有一个模型与描述的版本有一对多的关系。

在我的控制器中

$tag = Tags::create([
    'name' => $request->get('name'),
    'user_id' => \Auth::id(),
]);

$tag->update([
    'content' => $request->get('description')
]);

在我的模型中:

public function setContentAttribute(string $value)
{
    $this->versions()->create([
        'user_id' => \Auth::id(),
        'value' => $value
    ]);
}

所以我不能content直接作为属性放在create方法中,因为现在没有Model。

但是是否可以覆盖创建方法?

当我尝试在我的模型中覆盖这样的东西时,它会做一个无限循环

public static function create($attr) {
    return parent::create($attr);
}

所以我的问题是是否有可能有这样的东西:

$tag = Tags::create([
    'name' => $request->get('name'),
    'user_id' => \Auth::id(),
    'content' => $request->get('content')
]);

在模型中:

public static function create($attr) {
    $value = $attr['content'];
    $attr['content'] = null;
    $object = parent::create($attr);
    $object->content = $value;
    $object->save();
    return $object;
}

更新

我没有覆盖该create方法,而是调用了它customCreate。所以不再有无限循环,我可以将所有变量传递给customCreate为我处理关系的函数。

解决方案

在阅读了从 5.3 到 5.4 的更改后,原来 create 方法已被移动,因此您不必再调用parent::create()了。

最终解决方案是:

public static function create($attr) {
    $content = $attr['content'];
    unset($attr['content']);
    $element = static::query()->create($attr);
    $element->content = $content;
    $element->save();
    return $element;
}
4

1 回答 1

0

我不明白为什么不,您可能可以实施更通用的方法?例如。检查set{property}Attribute()方法是否存在,如果存在 - 使用它来分配值,如果不存在 - 使用质量分配。

就像是:

public static function create($attr) {
    $indirect = collect($attr)->filter(function($value, $property) {
        return method_exists(self::class, 'set' . camel_case($property) . 'Attribute');
    });

    $entity = parent::create(array_diff_key($attr, $indirect->toArray()));

    $indirect->each(function($value, $property) use ($entity) {
       $entity->{$property} = $value;
    });

    $entity->save();

    return $entity;
}

我还没有真正测试过它,但它应该可以工作。我在我的一个 Symfony 应用程序中使用了类似的东西。

于 2017-02-07T00:58:33.763 回答