私がLaravelについて気に入らない(少数の)ことの1つは、検証コードをコントローラーからモデルに簡単に移動できないことです。ソフトウェアを書くとき、私は「脂肪モデル、スキニーコントローラー」の原則を適用するのが好きです。ですから、私にとって、コントローラーに検証コードを書くことは良いことではありません。 これを解決するために、Laravel 4の素晴らしいパッケージであるArdentを紹介したいと思います。より正確には、Ardentは「Laravel Framework 4のEloquent ORMの自己検証スマートモデル」として現れます。言い換えれば、正確に必要なもの!
ご想像のとおり、基本的には雄弁なモデルクラスの拡張です。このパッケージには、入力検証などの新しい機能、ユーティリティ、およびメソッドが付属しています。
キーテイクアウト
id
first_name
メール
php artisan migrate:make todo_setup
テーブルがあります。モデルを作成する時が来ました。ここでも、書くべき行はほとんどありません。これがユーザーモデルです(これもデフォルトのモデルです)。
<span><span><?php </span></span><span> </span><span> <span>use Illuminate<span>\Database\Schema\Blueprint</span>; </span></span><span> <span>use Illuminate<span>\Database\Migrations\Migration</span>; </span></span><span> </span><span> <span>class TodoSetup extends Migration { </span></span><span> </span><span> <span>/** </span></span><span><span> * Run the migrations. </span></span><span><span> * </span></span><span><span> * <span>@return <span>void</span> </span></span></span><span><span> */ </span></span><span> <span>public function up() </span></span><span> <span>{ </span></span><span> <span>Schema<span>::</span>create('users', function(Blueprint $table) </span></span><span> <span>{ </span></span><span> <span>$table->increments('id')->unsigned(); </span></span><span> </span><span> <span>$table->string('first_name'); </span></span><span> <span>$table->string('last_name'); </span></span><span> <span>$table->string('email'); </span></span><span> <span>$table->string('password', 60); </span></span><span> </span><span> <span>$table->timestamps(); </span></span><span> <span>}); </span></span><span> </span><span> <span>Schema<span>::</span>create('tasks', function(Blueprint $table) </span></span><span> <span>{ </span></span><span> <span>$table->increments('id'); </span></span><span> </span><span> <span>$table->string('name'); </span></span><span> <span>$table->boolean('status'); </span></span><span> </span><span> <span>$table->integer('user_id')->unsigned(); </span></span><span> </span><span> <span>$table->timestamps(); </span></span><span> </span><span> <span>$table->index('user_id'); </span></span><span> <span>}); </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * Reverse the migrations. </span></span><span><span> * </span></span><span><span> * <span>@return <span>void</span> </span></span></span><span><span> */ </span></span><span> <span>public function down() </span></span><span> <span>{ </span></span><span> <span>Schema<span>::</span>dropIfExists('users'); </span></span><span> <span>Schema<span>::</span>dropIfExists('tasks'); </span></span><span> <span>} </span></span><span> </span><span> <span>}</span></span>
出発点を作成しました。これからは、インストールの直後に、2つの異なる状況が表示されます。まず、熱心なコードの「通常の」バージョンです。その後、「改善」バージョンと比較します。あなたは違いに気づくでしょう、私を信じてください。
<span><span><?php </span></span><span> </span><span> <span>use Illuminate<span>\Auth\UserTrait</span>; </span></span><span> <span>use Illuminate<span>\Auth\UserInterface</span>; </span></span><span> <span>use Illuminate<span>\Auth\Reminders\RemindableTrait</span>; </span></span><span> <span>use Illuminate<span>\Auth\Reminders\RemindableInterface</span>; </span></span><span> </span><span> <span>class User extends Eloquent implements UserInterface, RemindableInterface { </span></span><span> </span><span> <span>use UserTrait, RemindableTrait; </span></span><span> </span><span> <span>/** </span></span><span><span> * The database table used by the model. </span></span><span><span> * </span></span><span><span> * <span>@var <span>string</span> </span></span></span><span><span> */ </span></span><span> <span>protected $table = 'users'; </span></span><span> </span><span> <span>/** </span></span><span><span> * The attributes excluded from the model's JSON form. </span></span><span><span> * </span></span><span><span> * <span>@var <span>array</span> </span></span></span><span><span> */ </span></span><span> <span>protected $hidden = array('password', 'remember_token'); </span></span><span> </span><span> <span>public function tasks() </span></span><span> <span>{ </span></span><span> <span>return $this->hasMany('Task'); </span></span><span> <span>} </span></span><span> </span><span> <span>}</span></span>
始めましょう!
Ardent
のインストールその後、更新後、モデルに熱心なクラスを拡張する必要があります。
<span><span><?php </span></span><span> </span><span> <span>class Task extends <span>\Eloquent</span> { </span></span><span> <span>protected $fillable = []; </span></span><span> </span><span> <span>public function user() </span></span><span> <span>{ </span></span><span> <span>return $this->belongsTo('User'); </span></span><span> <span>} </span></span><span> <span>}</span></span>
…そして、あなたは行く準備ができています!
<span>{ </span> <span>"require": { </span> <span>"laravelbook/ardent": "2.*" </span> <span>} </span> <span>}</span>
最初に行うことは、熱心がどのように検証の実装において私たちの生活を容易にするかを分析することです。 Laravelでそれを行う方法をすでに知っています。古典的な例を作成しましょう:フォームから入るデータを処理するPOSTメソッド。
…アーデントではどうですか?
熱心で、物事は少し変わります。まず第一に、簡単に想像できるように、検証ルールはモデルに直接移動されます。「Restyle」を開始するのはここにあります。したがって、モデルファイルを開き、そのように変更してください:
<span><span><?php </span></span><span> <span>class User extends <span>\LaravelBook\Ardent\Ardent</span> { </span></span><span> <span>// model code here! </span></span><span> <span>}</span></span>
何が起こったのですか?あまり:モデルのベースクラス(雄弁から熱心に)を変更し、ここで検証ルールをカスタムエラーメッセージで(同じ構文を使用して)移動しました。
それで、今の質問は次のとおりです。コントローラーに何を書くつもりですか?
<span><span><?php </span></span><span> </span><span> <span>public function postSignup() </span></span><span> <span>{ </span></span><span> <span>$rules = array( </span></span><span> <span>'first_name' => 'required', </span></span><span> <span>'last_name' => 'required', </span></span><span> <span>'email' => 'required|email|unique:users', </span></span><span> <span>'password' => 'required|min:8' </span></span><span> <span>); </span></span><span> </span><span> <span>$messages = array( </span></span><span> <span>'first_name.required' => 'First name is required.', </span></span><span> <span>'last_name.required' => 'Last name is required.', </span></span><span> <span>'email.required' => 'Email is required.', </span></span><span> <span>'password.required' => 'Password is required.', </span></span><span> </span><span> <span>'email.email' => 'Use a real email address!', </span></span><span> <span>'email.unique' => 'This email address already exists!', </span></span><span> <span>'password.min' => 'Password must be at least 8 character long.' </span></span><span> <span>); </span></span><span> </span><span> <span>$validator = Validator<span>::</span>make(Input<span>::</span>all(), $rules, $messages); </span></span><span> </span><span> <span>if($validator->fails()) </span></span><span> <span>{ </span></span><span> <span>return Redirect<span>::</span>to('user/signup')->with('errors', $validator->messages()); </span></span><span> <span>} </span></span><span> </span><span> <span>$user = new User; </span></span><span> </span><span> <span>$user->first_name = Input<span>::</span>get('first_name'); </span></span><span> <span>$user->last_name = Input<span>::</span>get('last_name'); </span></span><span> <span>$user->email = Input<span>::</span>get('email'); </span></span><span> <span>$user->password = Hash<span>::</span>make(Input<span>::</span>get('password')); </span></span><span> </span><span> <span>if($user->save()) </span></span><span> <span>{ </span></span><span> <span>$status = 1; </span></span><span> <span>} </span></span><span> <span>else </span></span><span> <span>{ </span></span><span> <span>$status = 0; </span></span><span> <span>} </span></span><span> </span><span> <span>return Redirect<span>::</span>to('user/signup')->with('status', $status); </span></span><span> <span>}</span></span>
ここにはこれ以上検証手順はありません。彼らはすべて姿を消した。ただし、「移動」だけではありません。$ user-> save()メソッドは、検証フェーズにいくつかの問題がある場合、falseを返します。次に、$ user-> errors() - > all()メソッドでエラーを取得できます。奇妙なクラスはありません:返されたオブジェクトは、Laravelで作業している間にすでに出会った可能性のある古典的なメッセージバッグです。
ただし、必要に応じて、$ user-> balidationerrorsプロパティを使用することもできます。その場合、またはフィールド固有のエラーを取得する場合は、$ user-> balidationerrors-> get( 'field_name')を使用してください。さて、あなたは「OK、しかし、コードの行が少ないことを超えて、本当の利点は何ですか?」
最も重要なことから始めましょう。コード組織を改善すると、プロジェクトの保守性が向上します。簡単なアプリケーションでは、優先事項とは感じられませんが、より大きなプロジェクトに関しては、1つの間違った決定を簡単に台無しにすることができます。現実世界の状況の例を作りましょう。私たちは素晴らしいToDoリストアプリケーションを開発しましたが、それは本当に急速に成長しています。モバイルアプリケーションには間違いなくRESTFUL APIが必要です。コントローラーを「通常」の方法で使用することは、APIの別のサインアップルーチンを書き込むことを意味します。同じコードを持つ2つの異なるブロック!これは良くありません。古き良き乾燥(自分自身を繰り返さないでください)の原則はどこですか?
したがって、ベストプラクティスは、すべてを処理するモデルにsignup()メソッドを作成することです。 Ardentを使用すると、検証から保存手順まで、本当にすべてを処理することを意味します。それがなければ、最初のフェーズを達成することはできませんでした
2番目の利点は、より実用的なものです。モデルオートhydrateです。一緒に発見しましょう。モデル自動hydrate
php artisan migrate:make todo_setup
Ardentには、モデルの自動水和物機能があります。これは、オブジェクトを作成して$ user-> save()メソッドを呼び出すと、すべてのフィールドが入力オブジェクトデータで自動的に満たされることを意味します。もちろん、それに応じてすべてのフォームフィールドで正しい名前を付ける必要があります。
したがって、このコード:
は
<span><span><?php </span></span><span> </span><span> <span>use Illuminate<span>\Database\Schema\Blueprint</span>; </span></span><span> <span>use Illuminate<span>\Database\Migrations\Migration</span>; </span></span><span> </span><span> <span>class TodoSetup extends Migration { </span></span><span> </span><span> <span>/** </span></span><span><span> * Run the migrations. </span></span><span><span> * </span></span><span><span> * <span>@return <span>void</span> </span></span></span><span><span> */ </span></span><span> <span>public function up() </span></span><span> <span>{ </span></span><span> <span>Schema<span>::</span>create('users', function(Blueprint $table) </span></span><span> <span>{ </span></span><span> <span>$table->increments('id')->unsigned(); </span></span><span> </span><span> <span>$table->string('first_name'); </span></span><span> <span>$table->string('last_name'); </span></span><span> <span>$table->string('email'); </span></span><span> <span>$table->string('password', 60); </span></span><span> </span><span> <span>$table->timestamps(); </span></span><span> <span>}); </span></span><span> </span><span> <span>Schema<span>::</span>create('tasks', function(Blueprint $table) </span></span><span> <span>{ </span></span><span> <span>$table->increments('id'); </span></span><span> </span><span> <span>$table->string('name'); </span></span><span> <span>$table->boolean('status'); </span></span><span> </span><span> <span>$table->integer('user_id')->unsigned(); </span></span><span> </span><span> <span>$table->timestamps(); </span></span><span> </span><span> <span>$table->index('user_id'); </span></span><span> <span>}); </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * Reverse the migrations. </span></span><span><span> * </span></span><span><span> * <span>@return <span>void</span> </span></span></span><span><span> */ </span></span><span> <span>public function down() </span></span><span> <span>{ </span></span><span> <span>Schema<span>::</span>dropIfExists('users'); </span></span><span> <span>Schema<span>::</span>dropIfExists('tasks'); </span></span><span> <span>} </span></span><span> </span><span> <span>}</span></span>
13行目から、サインアップ手順全体で7回に下ったばかりです。
<span><span><?php </span></span><span> </span><span> <span>use Illuminate<span>\Auth\UserTrait</span>; </span></span><span> <span>use Illuminate<span>\Auth\UserInterface</span>; </span></span><span> <span>use Illuminate<span>\Auth\Reminders\RemindableTrait</span>; </span></span><span> <span>use Illuminate<span>\Auth\Reminders\RemindableInterface</span>; </span></span><span> </span><span> <span>class User extends Eloquent implements UserInterface, RemindableInterface { </span></span><span> </span><span> <span>use UserTrait, RemindableTrait; </span></span><span> </span><span> <span>/** </span></span><span><span> * The database table used by the model. </span></span><span><span> * </span></span><span><span> * <span>@var <span>string</span> </span></span></span><span><span> */ </span></span><span> <span>protected $table = 'users'; </span></span><span> </span><span> <span>/** </span></span><span><span> * The attributes excluded from the model's JSON form. </span></span><span><span> * </span></span><span><span> * <span>@var <span>array</span> </span></span></span><span><span> */ </span></span><span> <span>protected $hidden = array('password', 'remember_token'); </span></span><span> </span><span> <span>public function tasks() </span></span><span> <span>{ </span></span><span> <span>return $this->hasMany('Task'); </span></span><span> <span>} </span></span><span> </span><span> <span>}</span></span>
done!
また、ビジネスロジックには必要ない冗長なデータがあることがよくあります。 _confirmationフィールドまたはCSRFトークンについて考えてください。さて、モデルの$ autopurgeredundantattributesプロパティでそれらを捨てることができます。前と同じように、それをtrueに切り替えてください。
<span><span><?php </span></span><span> </span><span> <span>class Task extends <span>\Eloquent</span> { </span></span><span> <span>protected $fillable = []; </span></span><span> </span><span> <span>public function user() </span></span><span> <span>{ </span></span><span> <span>return $this->belongsTo('User'); </span></span><span> <span>} </span></span><span> <span>}</span></span>
今では、手順は以前よりもきれいです。
モデルフック
<span>{ </span> <span>"require": { </span> <span>"laravelbook/ardent": "2.*" </span> <span>} </span> <span>}</span>
これらすべての方法のリストを次に示します
php artisan migrate:make todo_setup
beforesave()とabhersave()についての特定のヒントもあります。実行時に宣言できます。見てください:
アプリケーションでのこれらのメソッドのいくつかの可能な用途について考えてみましょう。
<span><span><?php </span></span><span> </span><span> <span>use Illuminate<span>\Database\Schema\Blueprint</span>; </span></span><span> <span>use Illuminate<span>\Database\Migrations\Migration</span>; </span></span><span> </span><span> <span>class TodoSetup extends Migration { </span></span><span> </span><span> <span>/** </span></span><span><span> * Run the migrations. </span></span><span><span> * </span></span><span><span> * <span>@return <span>void</span> </span></span></span><span><span> */ </span></span><span> <span>public function up() </span></span><span> <span>{ </span></span><span> <span>Schema<span>::</span>create('users', function(Blueprint $table) </span></span><span> <span>{ </span></span><span> <span>$table->increments('id')->unsigned(); </span></span><span> </span><span> <span>$table->string('first_name'); </span></span><span> <span>$table->string('last_name'); </span></span><span> <span>$table->string('email'); </span></span><span> <span>$table->string('password', 60); </span></span><span> </span><span> <span>$table->timestamps(); </span></span><span> <span>}); </span></span><span> </span><span> <span>Schema<span>::</span>create('tasks', function(Blueprint $table) </span></span><span> <span>{ </span></span><span> <span>$table->increments('id'); </span></span><span> </span><span> <span>$table->string('name'); </span></span><span> <span>$table->boolean('status'); </span></span><span> </span><span> <span>$table->integer('user_id')->unsigned(); </span></span><span> </span><span> <span>$table->timestamps(); </span></span><span> </span><span> <span>$table->index('user_id'); </span></span><span> <span>}); </span></span><span> <span>} </span></span><span> </span><span> <span>/** </span></span><span><span> * Reverse the migrations. </span></span><span><span> * </span></span><span><span> * <span>@return <span>void</span> </span></span></span><span><span> */ </span></span><span> <span>public function down() </span></span><span> <span>{ </span></span><span> <span>Schema<span>::</span>dropIfExists('users'); </span></span><span> <span>Schema<span>::</span>dropIfExists('tasks'); </span></span><span> <span>} </span></span><span> </span><span> <span>}</span></span>
たぶん、パスワードハッシュを処理するbeforesave()?
ユーザーが手順を削除する直前に
またはクリーニングフック?<span><span><?php </span></span><span> </span><span> <span>use Illuminate<span>\Auth\UserTrait</span>; </span></span><span> <span>use Illuminate<span>\Auth\UserInterface</span>; </span></span><span> <span>use Illuminate<span>\Auth\Reminders\RemindableTrait</span>; </span></span><span> <span>use Illuminate<span>\Auth\Reminders\RemindableInterface</span>; </span></span><span> </span><span> <span>class User extends Eloquent implements UserInterface, RemindableInterface { </span></span><span> </span><span> <span>use UserTrait, RemindableTrait; </span></span><span> </span><span> <span>/** </span></span><span><span> * The database table used by the model. </span></span><span><span> * </span></span><span><span> * <span>@var <span>string</span> </span></span></span><span><span> */ </span></span><span> <span>protected $table = 'users'; </span></span><span> </span><span> <span>/** </span></span><span><span> * The attributes excluded from the model's JSON form. </span></span><span><span> * </span></span><span><span> * <span>@var <span>array</span> </span></span></span><span><span> */ </span></span><span> <span>protected $hidden = array('password', 'remember_token'); </span></span><span> </span><span> <span>public function tasks() </span></span><span> <span>{ </span></span><span> <span>return $this->hasMany('Task'); </span></span><span> <span>} </span></span><span> </span><span> <span>}</span></span>
多くの可能性があります。
<span><span><?php </span></span><span> </span><span> <span>class Task extends <span>\Eloquent</span> { </span></span><span> <span>protected $fillable = []; </span></span><span> </span><span> <span>public function user() </span></span><span> <span>{ </span></span><span> <span>return $this->belongsTo('User'); </span></span><span> <span>} </span></span><span> <span>}</span></span>
関係の定義(熱心な方法)
ARDENTを使用して関係を定義することは、$ RelationsDataと呼ばれる単純な配列を定義することを意味します。
<span>{ </span> <span>"require": { </span> <span>"laravelbook/ardent": "2.*" </span> <span>} </span> <span>}</span>
ただし、できることはたくさんあります:
<span><span><?php </span></span><span> <span>class User extends <span>\LaravelBook\Ardent\Ardent</span> { </span></span><span> <span>// model code here! </span></span><span> <span>}</span></span>
$ RelationsDataのすべての要素には、キー(はい、関係のメソッド名)といくつかのパラメーターがある配列があります。
最初のパラメーター(キーなしで、最初のパラメーター)は、関係タイプ(hasone、hasmany、belongsto、belongstomany、morpho、morphone、morphmany)を説明しています。
2番目のパラメーター(キーなしで、2番目のパラメーター)は、現在の関係の宛先モデルを定義します。<span><span><?php </span></span><span> </span><span> <span>public function postSignup() </span></span><span> <span>{ </span></span><span> <span>$rules = array( </span></span><span> <span>'first_name' => 'required', </span></span><span> <span>'last_name' => 'required', </span></span><span> <span>'email' => 'required|email|unique:users', </span></span><span> <span>'password' => 'required|min:8' </span></span><span> <span>); </span></span><span> </span><span> <span>$messages = array( </span></span><span> <span>'first_name.required' => 'First name is required.', </span></span><span> <span>'last_name.required' => 'Last name is required.', </span></span><span> <span>'email.required' => 'Email is required.', </span></span><span> <span>'password.required' => 'Password is required.', </span></span><span> </span><span> <span>'email.email' => 'Use a real email address!', </span></span><span> <span>'email.unique' => 'This email address already exists!', </span></span><span> <span>'password.min' => 'Password must be at least 8 character long.' </span></span><span> <span>); </span></span><span> </span><span> <span>$validator = Validator<span>::</span>make(Input<span>::</span>all(), $rules, $messages); </span></span><span> </span><span> <span>if($validator->fails()) </span></span><span> <span>{ </span></span><span> <span>return Redirect<span>::</span>to('user/signup')->with('errors', $validator->messages()); </span></span><span> <span>} </span></span><span> </span><span> <span>$user = new User; </span></span><span> </span><span> <span>$user->first_name = Input<span>::</span>get('first_name'); </span></span><span> <span>$user->last_name = Input<span>::</span>get('last_name'); </span></span><span> <span>$user->email = Input<span>::</span>get('email'); </span></span><span> <span>$user->password = Hash<span>::</span>make(Input<span>::</span>get('password')); </span></span><span> </span><span> <span>if($user->save()) </span></span><span> <span>{ </span></span><span> <span>$status = 1; </span></span><span> <span>} </span></span><span> <span>else </span></span><span> <span>{ </span></span><span> <span>$status = 0; </span></span><span> <span>} </span></span><span> </span><span> <span>return Redirect<span>::</span>to('user/signup')->with('status', $status); </span></span><span> <span>}</span></span>
laravel eloquentのAPIリソースを使用すると、モデルとモデルコレクションをJSON形式に変換してAPIで使用できます。モデルの変換方法を定義するリソースクラスを作成し、APIルートからそのリソースクラスのインスタンスを返すことができます。保存する前に、モデルで定義された一連のルールに対するモデルの属性。検証が失敗した場合、保存操作が中止され、ERRORS()メソッドを使用して検証エラーが利用可能です。 ()Laravel Eloquentのメソッドは、モデルが「起動」されているとき、つまりメモリにロードされたときに呼び出されるライフサイクルフックです。このメソッドをモデルにオーバーライドして、イベントリスナーの登録やモデルの構成のカスタマイズなど、モデルの起動時に発生する動作を追加できます。
以上がARDENT:ステロイドのLaravelモデルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。