Laravel 5如何在验证之前运行mutator

时间:2017-08-14 19:07:54

标签: php laravel-5

我在Laravel(第一个项目)非常环保,所以如果我犯了新手错误,请耐心等待。我试图通过Laracasts创建这个项目,所以我使用他的建议。我使用的是Laravel 5.4和PHP 7.1.4

我在布尔字段的表单上有一个复选框。如果在提交表单时未选中该复选框,则返回null。我不想要布尔值的空值,所以我有一个验证器,确保它只接受真/假值。为了使其工作,我必须创建一个mutator,如果它为null,则将值更改为false。

我有两个模型,Item和ItemNote。我试图从Item模型创建ItemNote。在Item页面上有一个添加ItemNote的地方,它运行到ItemNoteController,然后我在Item中调用一个方法来添加ItemNote。问题是我无法在ItemNote模型中运行mutator,因此验证失败,因为布尔字段(calendar_item)为空。

我起初尝试从与Item的关系创建ItemNote,根据这个堆栈溢出Laravel 5 mutators only work when I create a record and not when I update a record回答,当通过关系创建mutator时不会运行$ this-> notes() - > create ($请求 - >所有())。你必须使用模型$ this-> notes-> create($ request-> all())注意注释后没有括号。所以我已经尝试了一切我可能想到的尝试通过模型创建对象,但仍然无法让mutator运行。

以下是我模型中的关系声明:

项目

public function notes() { return $this->hasMany(ItemNote::class); }

ItemNote

public function item() { return $this->belongsTo(Item::class); }

CalendarNite的ItemNote中的Mutator

protected function setCalendarItemAttribute($value) { $this->attributes['calendar_item'] = isset($value) ? $value : FALSE; }

ItemNote中的验证规则

public static $validationRules = array('note_date' => 'required|date',
                                           'resolve_date' => 'nullable|date',
                                           'notes' => 'required|string',
                                           'cost' => 'nullable|numeric',
                                           'calendar_item' => 'required|boolean',
                                           'attachment_path' => 'nullable|string|max:200');

这是在ItemNoteController中从Item项页面添加ItemNote时运行的操作

public function store(Item $item)
{
    $this->validate(request(), ItemNote::$validationRules);

    $item->addNote(new ItemNote(request(['item_note_category_id', 'note_date', 'resolve_date', 
                                        'notes', 'cost', 'calendar_item', 'attachment_path'])));

    return back();
}

以下是Item模型中的函数addNote

public function addNote(ItemNote $note)
{
    $this->item_note->save($note);
}

以下是我在addNote中尝试的不同内容,它们都无法运行mutator。 create语句列出了字段分配,但为了简洁我在这里删除了它们。

$this->notes->save($note);
$this->notes()->save($note);
$this->item_note->save($note);
$this->notes->create
$this->item_notes->create
$this->item_notes()->create
$this->item_note->create
$this->item_note()->create
$this->ItemNote->create
$this->ItemNote()->create
ItemNote::create

上述所有工作,虽然我认为$ this-> item_notes->创建根本不起作用,因为关系名称是注释,但它没有抱怨让我认为它可能无法访问此代码,并且它在控制器中的validate语句上失败。如何在验证之前运行mutators?或者在验证之前是否有更好的方法来清理数据?

我还尝试将item_id字段放在验证规则中,但总是失败,因为在我通过关系创建对象之前未分配item_id。我想要它,但还没有想出如何在请求中分配它。

感谢任何帮助。对不起,很长的帖子。

1 个答案:

答案 0 :(得分:0)

你的变种人在你的模特身上。而您正在使用ValidatesRequests控制器特性来验证您的请求输入数据。因此,只有在运行验证后才会调用mutators。

因此,我发现您有两种选择。

一个。修改HTML以确保始终收到布尔值。例如,使用具有默认值的隐藏输入。如果未选中该复选框,则仅提交此值。

<input name="example" type="hidden" value="0">
<input name="example" type="checkbox" value="1">

湾为您的模型加水,调用您的mutator,然后运行验证。

$itemNote = new ItemNote($request->all());
$request->merge($itemNote->toArray());

$this->validate($request, ItemNote::$validationRules);
// ...

编辑:以下是我的模型验证的一些链接。它可能是有用的,并给你自己的想法。

https://gist.github.com/robsimpkins/2fe0de2483d51f1e4446ec90be7d96ae https://gist.github.com/robsimpkins/6a2f20853a2d01260ab299ebcebf9673 https://gist.github.com/robsimpkins/7df10abce1cdc07593d8c872a5461425 https://gist.github.com/robsimpkins/c4aa0517a80b794a2d347912100bd6d9