【问题标题】:How to use unique validation in laravel?如何在 laravel 中使用唯一验证?
【发布时间】:2016-12-09 20:37:32
【问题描述】:

我有 cmets 表:

我的评论控制器,它从表单中获取值并验证它并将其存储在数据库中。

public function store(Request $request, $product_id)
    {
        $this->validate($request, array(
            'name' => 'required',
            'email'=> 'required|email|unique:comments,product_id',
            'comment' => 'required',
            'rating' => 'required|integer'
            ));
        $product = Product::find($product_id);
        $comment = new Comment();
        $comment->name = $request->name;
        $comment->email = $request->email;
        $comment->comment = $request->comment;
        $comment->rating = $request->rating;
        $comment->product()->associate($product);

        $comment->save();
        Session::flash('success','Comment was added');
        return redirect()->route('product.show',[$product->id]);
    }

我正在尝试验证,只有唯一的电子邮件 ID 才能对每个 product_id 发表评论,也就是说,如果用户已经对 product_id 1 发表了评论,则不允许同一用户再次对该 id 发表评论。强>

我试过了

'email'=> 'required|email|unique:comments,product_id'

但正如您所见,为相同的 product_id 输入了相同的电子邮件 ID 数据。

用户可以对 n 个 product_id 页面发表评论,但一旦评论了该 id,便无法再次发表评论。

是否有办法验证是否已在数据库中为特定 product_id 输入电子邮件数据,然后不允许同一电子邮件提交表单。

如果 product_id 不同,则 email 可以输入。

谢谢。

【问题讨论】:

    标签: laravel


    【解决方案1】:

    在你的控制台中写下这个

    php artisan make:provider ValidationServiceProvider
    

    然后用

    替换您的 App\Providers\ValidationServiceProvider
    namespace App\Providers;
    
    use Validator;
    use App\Comment;
    use Illuminate\Support\ServiceProvider;
    
    class ValidationServiceProvider extends ServiceProvider
    {
      /**
       * Bootstrap any application services.
       *
       * @return void
       */
      public function boot() {
        Validator::extend('unique_email_comment', function($attribute, $value, $parameters, $validator) {
          return !Comment::where('email', $value)->where('product_id', $parameters[0])->exists();
        });
      }
    
      /**
       * Register the service provider.
       *
       * @return void
       */
      public function register() {
        //
      }
    }
    

    注意:-请确保将 Model App\Comment 替换为您用于 cmets 系统的模态名称空间。

    现在将其添加到config/app.php 中的providers 喜欢

    App\Providers\ValidationServiceProvider::class,
    

    现在,您可以通过以下方式验证行的存在:

    'email' => 'unique_email_comment:' . $productId;
    
    // or
    // 'email' => 'unique_email_comment:' . request()->get('product_id');
    

    您也可以像这样添加自定义消息

    return [
      'email.unique_email_comment' => 'A comment has already been made for this product with the email provided';
    ]
    

    请注意,我没有测试代码,但如果所有数据都正确传递并且所有命名空间都正确使用,这应该可以工作。

    【讨论】:

    • @Phoenix 很高兴我能帮上忙 :)
    • 我在哪里添加自定义消息
    • 只需自定义$messages = [....] 并将其作为第三个参数添加到Validator::make() 就像Validator::make($inputs, $rules, $messages) 一样
    【解决方案2】:

    unique 规则不是这样工作的。对于您的任务,您需要创建自定义验证规则并手动检查使用此电子邮件的用户是否已经评论了此产品。

    https://laravel.com/docs/5.3/validation#custom-validation-rules

    【讨论】:

    • 能否请您根据上述问题创建一个示例规则,因为我在阅读文档后无法弄清楚,因为我对 laravel 不是很有经验。谢谢。
    【解决方案3】:

    您是否尝试过unique_with 自定义验证。可能是这个包完全满足您的要求。您可以查看并获取示例here

    【讨论】:

      【解决方案4】:

      您无法将多列用于唯一规则。您必须通过触发查询来手动检查。

      【讨论】:

        【解决方案5】:

        您可以使用验证规则uniqueReference

        use Illuminate\Validation\Rule;

        $this->validate($request, array(
             'name' => 'required',
             'email'=> ['required', 'email', Rule::unique('comments', 'email')->where(function($query) {
                            $query->where('product_id', $product_id);
                       })],
             ...
        ));
        

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 2018-07-29
          • 1970-01-01
          • 2022-01-12
          • 1970-01-01
          • 2015-04-13
          • 2017-10-11
          • 2016-11-07
          • 2017-11-02
          • 1970-01-01
          相关资源
          最近更新 更多