現在、テキストフィールドとスラッグフィールドを持つモデルがあります。
フォームリクエストクラスでスラッグが一意であることを検証します。
public function rules()
{
return [
'name' => 'required|min:3',
'slug' => 'required|alpha_dash|unique:questions'
];
}
これは作成時に正常に機能し、重複するスラッグの作成を適切に拒否します。ただし、私の更新方法では、スラッグがすでに存在するため、レコードを保存できません。もちろんスラッグは存在しますが、編集中のレコードに存在するので、引き続き保存していきたいと思います。ただし、別のレコードのスラッグに変更することはできません。
私の更新ArticlesControllerメソッドは次のようになります。
public function update(Article $article, ArticleRequest $request)
{
$article->update($request->all());
return redirect('articles');
}
L5でこれを機能させる方法はありますか?
一意のルール で、無視するIDを指定できます。
2つの別々のリクエスト(1つは作成用、もう1つは更新用)を作成できますが、この方法で設定されているかどうかを確認することもできます(更新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;
}
}
次のようにルールを変更してみてください(フォームリクエストクラスで):
public function rules()
{
return [
'name' => 'required,min:3',
'slug' => 'required|alpha_dash|unique:categories,slug,'.$this->id')
];
}
わたしにはできる。
スラッグを更新する機能が必要な場合、私が取り組んだプロジェクトでは通常、作成後に編集できないようにする必要があります。その後、laravelの組み込みルールを使用して、テーブル上の特定のレコードを主キーで無視できます。
$rules['slug'] = "required|unique:questions,slug,{$id}";
http://laravel.com/docs/5.0/validation 「特定のIDを無視するように一意のルールを強制する」を参照してください
これが私がLaravel 5.3でそれを行う方法の詳細です:
1-ターミナルで次のコマンドを実行して、新しいフォームリクエストクラスを作成します。
_php artisan make:request ArticleFormRequest
_
ここで、ArticleFormRequest
はフォームリクエストクラスの名前です。このコマンドは、_ArticleFormRequest.php
_ディレクトリに_app/Http/Requests
_というファイルを作成します。
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..
}
}
_
EditArticleRequest:
public function $rules ()
{
$id = $this->id;
return [
'name' => 'required|min:3',
'slug' => "required|alpha_dash|unique:articles,slug,$id",
];
}
すでに述べたように、バリデータ機能で無視機能を使用できます。
無視したいアイテムの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;
}