在create函数内创建Relationship

时间:2017-02-06 21:32:23

标签: laravel eloquent relationship laravel-5.4

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

在我的控制器中

$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。

但是可以覆盖create方法吗?

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

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的变化后,结果表明创建方法已被移动,因此您不必再调用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;
}

1 个答案:

答案 0 :(得分: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应用程序中使用了类似的东西。