简体   繁体   English

使用条件消息进行Laravel自定义表单验证

[英]Laravel Custom Form Validation with Conditional Messages

I am building a Laravel-based eCommerce solution with a shopping cart. 我正在使用购物车构建基于Laravel的电子商务解决方案。 I have a page for each product where you can choose a product option, whether you want to subscribe, how often you want to receive shipments, the quantity you want, and then add it to your shopping cart. 我有一个每个产品的页面,您可以在其中选择产品选项,是否要订阅,您希望接收货物的频率,您想要的数量,然后将其添加到您的购物车。 I want to validate this combination of choices before adding to the customer's shopping cart. 我想在添加到客户的购物车之前验证这些选择组合。 To validate, I need to check against the database for this product option to make sure that it can be subscribed to, that the quantity chosen is below the maximum quantity allowed for that product, etc. 要进行验证,我需要针对此产品选项检查数据库,以确保可以订阅,所选数量低于该产品允许的最大数量等。

With CodeIgniter, I would write a custom callback, pull in the inputs from the POST request, and check everything in one call to the database. 使用CodeIgniter,我会编写一个自定义回调,从POST请求中提取输入,并在一次调用数据库时检查所有内容。 If there was a validation failure, I would then output a relevant conditional message for what caused the validation to fail. 如果验证失败,我会输出相关的条件消息,说明导致验证失败的原因。 (ie "You can't subscribe to that product" or "The quantity you selected is more than the maximum quantity allowed for the product.") (即“您无法订阅该产品”或“您选择的数量超过产品允许的最大数量。”)

This seems a little more difficult to accomplish with Laravel. 使用Laravel这似乎有点难以实现。 I was looking through the documentation and articles online, and I found an approach that seems to work. 我在线查看文档和文章,我发现了一种似乎有用的方法。

I have my validation method in my model, CartLine. 我的模型中有我的验证方法,CartLine。 Then, in a new Form Request, I overwrite the getValidatorInstance method with the following: 然后,在新的表单请求中,我用以下内容覆盖getValidatorInstance方法:

public function getValidatorInstance()
{
    $validator = parent::getValidatorInstance();

    $validator->after(function() use ($validator) {

        $cartLine = new CartLine;
        $cartLine->validate($this->all());

        if (!$cartLine->valid()) {
            $validator->errors()->add('product', $cartLine->errors());
        }

    });

    return $validator;
}

I have a couple of questions: 我有一些问题:

  1. When I first experimented with this solution, I tried to use method injection for the instance of CarLine inside the closure, like so: 当我第一次尝试这个解决方案时,我尝试在闭包内使用CarLine实例的方法注入,如下所示:

     $validator->after(function(Validator $validator, CartLine $cartLine) use ($validator) { $cartLine->validate($this->all()); if (!$cartLine->valid()) { $validator->errors()->add('product', $cartLine->errors()); } }); 

    But I kept getting an error saying that the closure was expecting an instance of CartLine and none was given. 但我一直收到一个错误,说关闭期待CartLine的一个实例并且没有给出。 I fixed this by newing up CartLine inside the closure, but it's obviously not as elegant. 我通过在封闭内部新建CartLine来解决这个问题,但它显然不那么优雅。 Why doesn't method injection work here? 为什么方法注射不起作用?

  2. Does anyone have a better or more elegant solution for how to accomplish this type of custom validation with conditional error messages in Laravel? 有没有人有更好或更优雅的解决方案,如何在Laravel中使用条件错误消息完成此类自定义验证?

you may pass the custom messages as the third argument to the Validator::make method: 您可以将自定义消息作为第三个参数传递给Validator :: make方法:

$messages = [
'required' => 'The :attribute field is required.',];
 $validator = Validator::make($input, $rules, $messages);

Where :attribute will be replaced by actual name of field. 其中:属性将被字段的实际名称替换。

Also you can provide validations only for particular attribute as below 您也可以仅为特定属性提供验证,如下所示

$messages = [
'email.required' => 'We need to know your e-mail address!',];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM