我有一个与描述版本有一对多关系的模型。
在我的控制器中
$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;
}
答案 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应用程序中使用了类似的东西。