You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义数组验证规则StoreTicketTypeQuantity的实现需求

解决Laravel中票型购买数量的自定义验证规则问题

针对你提到的场景——用户提交多种票型的购买数量,需要验证每种数量是否符合TicketType表中对应票型的minPerUser和maxPerUser限制,我来一步步教你实现StoreTicketTypeQuantity这个自定义验证规则:

1. 生成自定义验证规则类

首先用Artisan命令快速生成规则文件:

php artisan make:rule StoreTicketTypeQuantity

这会在app/Rules目录下自动创建StoreTicketTypeQuantity.php文件。

2. 编写核心验证逻辑

打开生成的规则文件,替换passes和message方法的内容,实现针对每种票型的数量校验:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use App\Models\TicketType;

class StoreTicketTypeQuantity implements Rule
{
    // 用于存储错误信息的变量(可选优化)
    private $errorDetails = [];

    /**
     * 验证规则是否通过
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        // $value就是提交的types数组,格式如["ticket type 1" => "2", "ticket type 2" => "1"]
        foreach ($value as $ticketTypeName => $quantity) {
            // 把数量转为整数,避免字符串格式干扰
            $quantity = (int)$quantity;
            
            // 根据票型名称查找对应的数据库记录
            $ticketType = TicketType::where('name', $ticketTypeName)->first();
            
            // 情况1:票型不存在,直接验证失败
            if (!$ticketType) {
                $this->errorDetails = [
                    'type' => $ticketTypeName,
                    'message' => '不存在该票型'
                ];
                return false;
            }
            
            // 情况2:数量超出minPerUser和maxPerUser范围,验证失败
            if ($quantity < $ticketType->minPerUser || $quantity > $ticketType->maxPerUser) {
                $this->errorDetails = [
                    'type' => $ticketTypeName,
                    'min' => $ticketType->minPerUser,
                    'max' => $ticketType->maxPerUser
                ];
                return false;
            }
        }
        
        return true;
    }

    /**
     * 获取验证错误提示信息
     *
     * @return string
     */
    public function message()
    {
        // 根据不同错误场景返回精准提示
        if (isset($this->errorDetails['message'])) {
            return "票型「{$this->errorDetails['type']}」不存在,请检查后重试。";
        }
        return "票型「{$this->errorDetails['type']}」的购买数量不符合要求,每人限购{$this->errorDetails['min']}-{$this->errorDetails['max']}张。";
    }
}

注意:如果你的TicketType表中用slug或其他字段作为票型标识,记得把where('name', $ticketTypeName)改成对应的字段名。

3. 在控制器中使用该规则

在RegistrationController的存储方法里,把这个自定义规则加到验证逻辑中:

use App\Rules\StoreTicketTypeQuantity;

// ...

public function store(Request $request)
{
    $validatedData = $request->validate([
        'types' => ['required', 'array', new StoreTicketTypeQuantity],
        // 先给每个数量做基础校验:必须是正整数
        'types.*' => 'required|integer|min:1'
    ]);
    
    // 验证通过后,执行后续的订单创建等业务逻辑...
}

这样用户提交的每种票型数量都会被严格校验,不符合规则时会返回清晰的错误提示。

内容的提问来源于stack exchange,提问作者johnW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:57:34