【问题标题】:Validating a Unique Slug on Update in Laravel 5在 Laravel 5 中验证更新时唯一的 Slug
【发布时间】:2015-04-24 02:20:51
【问题描述】:

我目前有一个具有文本字段和 slug 字段的模型。

我确认 slug 在我的表单请求类中是唯一的:

public function rules()
{
    return [
        'name' => 'required|min:3',
        'slug' => 'required|alpha_dash|unique:questions'
    ];
}

这在创建时可以正常工作,并且可以正确地拒绝创建重复的 slug。但是在我的更新方法中,它不会让我保存记录,因为 slug 已经存在。当然 slug 确实存在,但它存在于正在编辑的记录中,所以我想继续允许它被保存。但是,它应该不能更改为 ANOTHER 记录上的 slug。

这是我的更新 ArticlesController 方法的样子:

public function update(Article $article, ArticleRequest $request)
{
    $article->update($request->all());

    return redirect('articles');
}

有没有办法在 L5 中完成这项工作?

【问题讨论】:

  • 我将暂时保持打开状态,看看还有哪些其他选项,但我已经通过删除我的验证并使用 Eloquent Sluggable 解决了这个问题:github.com/cviebrock/eloquent-sluggable

标签: php laravel laravel-5 laravel-validation laravel-request


【解决方案1】:

尝试修改您的规则,如下所示(在表单请求类中):

public function rules()
{
    return [
      'name'  => 'required,min:3',
      'slug'  => 'required|alpha_dash|unique:categories,slug,'.$this->id')
    ];
}

它对我有用。

【讨论】:

  • $this->id 是否依赖于Request 对象,该对象在路由中有一个名为id 的参数?喜欢/whatever/{id}。如果是/whatever/{whatever_id},我会使用$this->whatever_id 吗?
  • @MarcoAurélioDeleu 是的,你会的。
【解决方案2】:

在unique rule 中,您可以指定要忽略的 id。

您可以创建 2 个单独的请求(一个用于创建,一个用于更新),但您也可以通过这种方式检查是否已设置(我假设您的更新 url 看起来像 /questions/2):

public function rules()
{
    $rules = [
        'name' => 'required|min:3',
        'slug' => ['required', 'alpha_dash']
    ];

    $rule = 'unique:questions';

    $segments = $this->segments();
    $id = intval(end($segments));
    if ($id != 0) {  
         $rule .= ',slug,' . $id;
    }
    $rules['slug'][] = $rule;

    return $rules;
    }
}

【讨论】:

  • 我认为我的解决方案更干净一点! (但基本相同)
【解决方案3】:

如果你必须有更新 slug 的能力,我做过的项目通常要求它在创建后不可编辑,那么你可以使用 laravel 的内置规则通过主键忽略表上的某条记录。

$rules['slug'] = "required|unique:questions,slug,{$id}";

http://laravel.com/docs/5.0/validation 请参阅“强制唯一规则忽略给定 ID”

【讨论】:

    【解决方案4】:

    在EditArticleRequest中:

    public function $rules () 
    {
        $id = $this->id;
    
        return [
            'name' => 'required|min:3',
            'slug' => "required|alpha_dash|unique:articles,slug,$id",
        ];
    }
    

    【讨论】:

      【解决方案5】:

      这是我在 Laravel 5.3 中的详细操作方式:

      1- 通过在终端中执行下一个命令来创建一个新的 Form Request 类:

      php artisan make:request ArticleFormRequest
      

      其中ArticleFormRequest 是表单请求类的名称。该命令将在app/Http/Requests 目录中创建一个名为ArticleFormRequest.php 的文件。

      2- 打开创建的文件并删除其内容,然后将下一个内容放入其中:

      <?php
      
      namespace App\Http\Requests;
      
      use Illuminate\Foundation\Http\FormRequest;
      use Illuminate\Http\Request;
      use Illuminate\Validation\Rule;
      use App\Article;
      
      class ArticleFormRequest extends FormRequest
      {
          protected $rules = [
              'name' => 'required|min:3',
              'slug' => 'required|alpha_dash|unique:articles,slug',
          ];
      
          // protected $user; // in case you want the current authenticated user
          protected $request_method;
          protected $id;
      
          public function __construct(Request $request)
          {
              // $request->user() returns an instance of the authenticated user
              // $this->user = $request->user(); // in case you want the current authenticated user
      
              // $request->method() returns method of the request (GET, POST, PUT, DELETE, ...)
              $this->request_method = strtoupper($request->method());
      
              // segments(): Returns an array containing all of the segments for the request path
              // it is important to assign the returned "segments" array to a variable first before using it, otherwise an error will occur
              $segments = $request->segments();
              // note this way will be valid only if "id" of the element is the last segment
              $this->id = end($segments);
          }
      
          /**
           * Determine if the user is authorized to make this request.
           *
           * @return bool
           */
          public function authorize()
          {
              return true;
          }
      
          /**
           * Get the validation rules that apply to the request.
           *
           * @return array
           */
          public function rules()
          {
              $rules = $this->rules;
      
              if ($this->request_method == "POST") {
                  // do nothing..
              } elseif (in_array($this->request_method, ["PUT", "PATCH"])) {
                  $article = Article::find($this->id);
      
                  if ($article) {
                      // forcing a unique rule to ignore a given id | https://laravel.com/docs/5.3/validation
                      $rules["slug"] = [
                          "required",
                          "alpha_dash",
                          Rule::unique("articles", "slug")->ignore($article->id, "id"),
                      ];
      
                      // this is also can be used
                      // $rules['slug'] = "required|alpha_dash|unique:articles,slug,$article->id,id";
                  }
              }
      
              return $rules;
          }
      }
      

      3- 在您的控制器中,您可以在 store() 和 update() 方法中使用 ArticleFormRequest,如下所示:

      <?php
      
      namespace App\Http\Controllers;
      
      use App\Http\Requests\ArticleFormRequest;
      
      class ArticlesController extends Controller
      {
      
      
          public function store(ArticleFormRequest $request)
          {
              // your code here..
          }
      
          public function update(ArticleFormRequest $request, $id)
          {
              // Your code here..
          }
      
      }
      

      【讨论】:

        【解决方案6】:

        如前所述,您可以在验证器功能中使用忽略功能。

        只需引用您希望忽略的项目的 ID,并确保在更新时使用补丁请求!

        在这里查看更多信息! http://laravel.com/docs/5.0/validation#rule-unique

        protected $rules = [    
            'name' => 'required|min:3',
            'slug' => 'required|alpha_dash|unique:questions'
        ];
        
        public function rules()
        {
            $rules = $this->rules;
            if ($this->isMethod('patch')) 
            {
                $id = $this->articles;
                $rules['slug'] = $rules['slug'].',slug,'.$id;
            }
            return $rules;
        }
        

        【讨论】:

          猜你喜欢
          • 2014-06-28
          • 2018-08-09
          • 2019-02-26
          • 1970-01-01
          • 2014-08-20
          • 2018-07-17
          • 1970-01-01
          • 2016-05-31
          • 1970-01-01
          相关资源
          最近更新 更多