自定义验证始终在表单请求中返回 true Laravel

huangapple go评论137阅读模式
英文:

Custom validation always return true on form request laravel

问题

我有一个自定义验证用于我的表单请求。当用户输入值并且该值存在且字段 deleted_at 不为 null 时,此验证应该起作用。

问题是,即使我输入了不存在的值并且 deleted_at 为 null,验证仍然起作用。

这是我所做的:

customValidation:

  1. <?php
  2. namespace App\Rules;
  3. use Closure;
  4. use Illuminate\Contracts\Validation\Rule;
  5. use App\Models\Product;
  6. class SkuDeletedValidationRule implements Rule
  7. {
  8. /**
  9. * Run the validation rule.
  10. *
  11. * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
  12. */
  13. public function passes($attribute, $value)
  14. {
  15. // Retrieve the模型 instance based on the SKU value
  16. $model = Product::where('sku', $value)->first();
  17. // Check if the模型 exists and其 deleted_at 不为 null
  18. if ($model && $model->deleted_at !== null) {
  19. return true;
  20. }
  21. return false;
  22. }
  23. public function message()
  24. {
  25. return '该 :attribute 已存在但已被删除,请恢复它。';
  26. }
  27. }

我的表单请求:

  1. use App\Models\Product;
  2. use Illuminate\Foundation\Http\FormRequest;
  3. use Illuminate\Support\Str;
  4. use App\Rules\SkuDeletedValidationRule;
  5. class ProductRequest extends FormRequest
  6. {
  7. /**
  8. * Determine if the user is authorized to make this request.
  9. */
  10. public function authorize(): bool
  11. {
  12. return auth('cms-admin')->check();
  13. }
  14. /**
  15. * Get the validation rules that apply to the request.
  16. *
  17. * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array|string>
  18. */
  19. public function rules(): array
  20. {
  21. return [
  22. 'name' => 'required',
  23. 'sku' => [new SkuDeletedValidationRule, 'required' . $this->product->id],
  24. 'sku_merchant' => 'nullable|unique:products,sku_merchant,' . $this->product->id,
  25. 'slug' => 'nullable',
  26. 'is_publish' => 'required',
  27. 'price' => 'required',
  28. 'description' => 'required',
  29. 'discount' => 'nullable',
  30. 'images.*' => 'required',
  31. 'category.*' => 'nullable|exists:categories,id',
  32. 'supplier_id' => 'required',
  33. 'buyer_price' => 'required',
  34. ];
  35. }
  36. }

我的控制器:

  1. public function store(ProductRequest $request)
  2. {
  3. $this->productService->create($request->validated());
  4. return redirect(route('admin.product.index'))->with('success', '产品已创建!');
  5. }

当我输入不存在的值时,请修复我的自定义验证以使其正常工作。非常感谢!

英文:

I have custom validation for my form request. When users input the value and the value exists also field deleted_at is not null this validation should be working.

the problem is even when I input the value that is not exists and deleted_at is null. the validation still working.

this is what i have done

customValidation:

  1. &lt;?php
  2. namespace App\Rules;
  3. use Closure;
  4. use Illuminate\Contracts\Validation\Rule;
  5. use App\Models\Product;
  6. class SkuDeletedValidationRule implements Rule
  7. {
  8. /**
  9. * Run the validation rule.
  10. *
  11. * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
  12. */
  13. public function passes($attribute, $value)
  14. {
  15. // Retrieve the model instance based on the SKU value
  16. $model = Product::where(&#39;sku&#39;, $value)-&gt;first();
  17. // Check if the model exists and its deleted_at is not null
  18. if( $model &amp;&amp; $model-&gt;deleted_at !== null){
  19. return true;
  20. }
  21. return false;
  22. }
  23. public function message()
  24. {
  25. return &#39;The :attribute is exists but has been deleted, please restore it.&#39;;
  26. }
  27. }

my form request:

  1. use App\Models\Product;
  2. use Illuminate\Foundation\Http\FormRequest;
  3. use Illuminate\Support\Str;
  4. use App\Rules\SkuDeletedValidationRule;
  5. class ProductRequest extends FormRequest
  6. {
  7. /**
  8. * Determine if the user is authorized to make this request.
  9. */
  10. public function authorize(): bool
  11. {
  12. return auth(&#39;cms-admin&#39;)-&gt;check();
  13. }
  14. /**
  15. * Get the validation rules that apply to the request.
  16. *
  17. * @return array&lt;string, \Illuminate\Contracts\Validation\ValidationRule|array|string&gt;
  18. */
  19. public function rules(): array
  20. {
  21. return [
  22. &#39;name&#39; =&gt; &#39;required&#39;,
  23. &#39;sku&#39; =&gt; [new SkuDeletedValidationRule, &#39;required&#39; . $this-&gt;product?-&gt;id],
  24. &#39;sku_merchant&#39; =&gt; &#39;nullable|unique:products,sku_merchant,&#39; . $this-&gt;product?-&gt;id,
  25. &#39;slug&#39; =&gt; &#39;nullable&#39;,
  26. &#39;is_publish&#39; =&gt; &#39;required&#39;,
  27. &#39;price&#39; =&gt; &#39;required&#39;,
  28. &#39;description&#39; =&gt; &#39;required&#39;,
  29. &#39;discount&#39; =&gt; &#39;nullable&#39;,
  30. &#39;images.*&#39; =&gt; &#39;required&#39;,
  31. &#39;category.*&#39; =&gt; &#39;nullable|exists:categories,id&#39;,
  32. &#39;supplier_id&#39; =&gt; &#39;required&#39;,
  33. &#39;buyer_price&#39; =&gt; &#39;required&#39;
  34. ];
  35. }
  36. }

my Controller:

  1. public function store(ProductRequest $request)
  2. {
  3. $this-&gt;productService-&gt;create($request-&gt;validated());
  4. return redirect(route(&#39;admin.product.index&#39;))-&gt;with(&#39;success&#39;, &#39;product created!&#39;);
  5. }

when i input the non existing value

> 自定义验证始终在表单请求中返回 true Laravel

what to fix in my custom validation to be this working well? thank you in advanced.

答案1

得分: 1

要检索已经软删除的数据,您需要使用withTrashed()方法。

只需修改以下行:

  1. $model = Product::where('sku', $value)->first();

  1. $model = Product::withTrashed()->where('sku', $value)->first();

根据您的验证消息,我假设当您找到已经软删除的具有相同SKU的数据时,应该返回false。

  1. /**
  2. * 运行验证规则。
  3. *
  4. * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
  5. */
  6. public function passes($attribute, $value)
  7. {
  8. // 基于SKU值检索模型实例
  9. $model = Product::withTrashed()->where('sku', $value)->first();
  10. // 检查模型是否存在且其deleted_at不为null
  11. if ($model && $model->deleted_at !== null) {
  12. return false;
  13. }
  14. return true;
  15. }
英文:

To retrieve data that has been softly deleted, you need to use withTrashed() method.

Simply modify the following line:

  1. $model = Product::where(&#39;sku&#39;, $value)-&gt;first();

To

  1. $model = Product::withTrashed()-&gt;where(&#39;sku&#39;, $value)-&gt;first();

And based on your verification message, I assume you should return false when you find data with the same SKU that has been softly deleted.

  1. /**
  2. * Run the validation rule.
  3. *
  4. * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
  5. */
  6. public function passes($attribute, $value)
  7. {
  8. // Retrieve the model instance based on the SKU value
  9. $model = Product::withTrashed()-&gt;where(&#39;sku&#39;, $value)-&gt;first();
  10. // Check if the model exists and its deleted_at is not null
  11. if( $model &amp;&amp; $model-&gt;deleted_at !== null){
  12. return false;
  13. }
  14. return true;
  15. }

答案2

得分: 0

我认为你正在使用SoftDelete特性和架构。

如果你已经删除了它,你不能添加新的sku,你有两个选项。

如果之前删除过,请尝试这个:

  1. Product::withTrashed()->where('sku', $value)->restore();

或者你可以在插入新的之前强制删除它:

  1. Product::where('sku', $value)->forceDelete();
英文:

I think you are using SoftDelete traits and schema.

You can't add new sku if you have already deleted it you have two options.

Try this if previously deleted.

  1. Product::withTrashed()-&gt;where(&#39;sku&#39;, $value)-&gt;restore();

Or you can force delete it before inserting new

  1. Product::where(&#39;sku&#39;, $value)-&gt;forceDelete();

huangapple
  • 本文由 发表于 2023年8月10日 11:25:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76872471.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定