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

如何通过通用CrudInterface传递不同自定义请求并触发验证?

问题分析与解决方案

核心问题

你遇到的验证未触发问题,本质是Laravel的FormRequest验证逻辑仅在通过服务容器解析时自动执行,手动new CreateTagRequest()只是创建了对象,不会触发验证流程,因此rules()中的日志不会输出,空值也未被拦截,最终导致SQL非空约束错误。


解决方案

方案一:控制器注入自定义请求(推荐,符合Laravel设计模式)

直接在控制器方法参数中注入CreateTagRequest,Laravel会自动触发验证,验证失败时直接返回422错误,无需手动处理。

  1. 修改控制器代码:
public function store(CreateTagRequest $request)
{
    try {
        \Log::info(' -1 BEFORE CreateTagRequest::');
        // 直接使用验证通过的字段,避免手动筛选数据的误差
        $tag = $this->tagCrudRepository->store(
            data: $request->validated(),
            request: $request
        );
        // 后续逻辑(如返回响应)
    } catch (\Exception $e) {
        // 异常处理
    }
}
  1. 完善CreateTagRequest的验证规则:
class CreateTagRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        \Log::info( '-1 CreateTagRequest data::' . print_r( $this->all(), true  ) );
        return [
            'name' => 'required|string|max:255|unique:tags',
        ];
    }
}
  1. 仓库直接使用验证后的数据:
// TagCrudRepository
public function store(array $data, $request): Tag
{
    return Tag::create($data);
}

方案二:仓库中手动触发验证(适合需要保持控制器通用性的场景)

如果必须通过通用接口传递自定义请求,可在仓库内手动触发验证逻辑:

  1. 调整CrudInterface的类型声明:
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Database\Eloquent\Model;

interface CrudInterface
{
    public function store(array $data, FormRequest $request): Model;
}
  1. 在仓库的store方法中触发验证:
// TagCrudRepository
public function store(array $data, FormRequest $request): Tag
{
    // 触发验证,获取通过验证的字段
    $validatedData = $request->validated();
    return Tag::create($validatedData);
}
  1. 控制器中通过服务容器解析请求(确保绑定上下文):
public function store(Request $request)
{
    try {
        \Log::info(' -1 BEFORE CreateTagRequest::');
        // 用服务容器解析请求,自动绑定当前请求上下文
        $tagRequest = app(CreateTagRequest::class);
        $tag = $this->tagCrudRepository->store(
            data: $request->only('name'),
            request: $tagRequest
        );
    } catch (\Exception $e) {
        // 异常处理
    }
}

关键说明

  • 避免手动实例化FormRequest,因为这种方式不会触发Laravel内置的验证流程;
  • $request->validated()仅返回通过验证的字段,比手动only()更安全,能避免遗漏验证规则;
  • 验证规则中添加required约束后,空值会被拦截,从根源解决SQL非空约束错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 21:32:46