2015-02-22 22 views
12

Tôi hiện có một mô hình có trường văn bản và trường slug.Xác nhận một Slug duy nhất trên Bản cập nhật trong Laravel 5

Tôi xác nhận rằng sên là duy nhất trong lớp yêu cầu hình thức của tôi:

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

này làm việc tốt trên tạo và đúng cách phủ nhận sự sáng tạo của sên trùng lặp. Tuy nhiên trên phương pháp cập nhật của tôi, nó sẽ không cho phép tôi lưu một bản ghi vì slug đã tồn tại. Tất nhiên slug không tồn tại, nhưng nó tồn tại trên hồ sơ đang được chỉnh sửa, vì vậy tôi muốn tiếp tục cho phép nó được lưu lại. Tuy nhiên, nó sẽ không thể được thay đổi thành một slug trên hồ sơ KHÁC.

Đây là những gì cập nhật phương pháp ArticlesController của tôi trông giống như:

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

    return redirect('articles'); 
} 

Có cách nào để làm cho công việc này trong L5?

+0

Tôi sẽ để nguyên mục này để xem các tùy chọn khác tồn tại, nhưng tôi đã giải quyết vấn đề này bằng cách xóa xác thực của tôi và sử dụng Eloquent Sluggable: https://github.com/cviebrock/eloquent-sluggable – Rapture

Trả lời

3

Trong unique rule bạn có thể chỉ định id bạn muốn bỏ qua.

Bạn có thể tạo 2 yêu cầu riêng biệt (một cho tạo và một cho bản cập nhật), nhưng bạn có thể làm điều đó cũng theo cách này kiểm tra nếu nếu được thiết lập (tôi giả url cập nhật của bạn trông giống như /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; 
    } 
} 
+0

Tôi nghĩ rằng giải pháp của tôi là một chút sạch hơn! (nhưng về cơ bản giống nhau) –

2

Nếu bạn phải có khả năng cập nhật slug, các dự án tôi đã làm thường yêu cầu nó không thể chỉnh sửa sau khi tạo, sau đó bạn có thể sử dụng quy tắc dựng sẵn của laravel để bỏ qua một bản ghi nhất định trên bảng bằng khóa chính.

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

http://laravel.com/docs/5.0/validation see "Buộc một quy tắc duy nhất để bỏ qua một ID cho"

0

Như đã đề cập, bạn có thể sử dụng tính năng bỏ qua trong các chức năng xác nhận.

Chỉ cần tham chiếu id của mục bạn muốn bỏ qua và đảm bảo rằng khi bạn cập nhật, bạn sử dụng yêu cầu vá!

Xem thêm thông tin tại đây! 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; 
} 
2

Cố gắng sửa đổi quy tắc của bạn như sau (trong lớp yêu cầu theo mẫu):

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

Nó làm việc cho tôi.

+1

nào '$ this-> id' dựa vào đối tượng' Request' có tham số được gọi là 'id' trong tuyến đường? Giống như '/ whatever/{id}'. Nếu nó là '/ whatever/{whatever_id}' tôi sẽ sử dụng '$ this-> whatever_id'? –

1

Dưới đây là cách tôi làm điều đó trong Laravel 5.3 chi tiết:

1- Tạo một Mẫu Yêu cầu lớp mới bằng cách thực hiện lệnh tiếp theo trong terminal của bạn:

php artisan make:request ArticleFormRequest 

đâu ArticleFormRequest là tên của lớp yêu cầu biểu mẫu. Lệnh này sẽ tạo một tệp có tên là ArticleFormRequest.php trong thư mục app/Http/Requests.

2- mở đã tạo ra tập tin và loại bỏ nội dung của nó sau đó đặt các nội dung tiếp theo trong nó:

<?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- Trong điều khiển của bạn, bạn có thể sử dụng ArticleFormRequest trong store()update() phương pháp như thế này:

<?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.. 
    } 

} 
0

Trong EditArticleRequest:

public function $rules() 
{ 
    $id = $this->id; 

    return [ 
     'name' => 'required|min:3', 
     'slug' => "required|alpha_dash|unique:articles,slug,$id", 
    ]; 
} 
Các vấn đề liên quan