Laravel Framework 5 の Eloquent ORM の自己検証スマート モデル。
Colby Rabideau による Laravel 3 の Aware バンドルに基づいています。
著作権 (C) 2013-2015 マックス イーサン & イゴール サントス
リリースリストにアクセスしてください。変更ログはそこに作成されます:)
要件としてlaravelbook/ardent
をcomposer.json
に追加します(バッジにある最新の安定バージョンを参照してください)。
{"require": {"laravelbook/ardent": "3.*"}}
composer update
でパッケージを更新するか、 composer install
でインストールします。
また、 composer require laravelbook/ardent
使用してパッケージを追加し、後で必要なバージョンを指定することもできます (現時点では、 dev-master
最善の策です)。
Ardent をスタンドアロン ORM パッケージとして使用したい場合は、プロジェクトのブート/スタートアップ ファイルで次の構成を使用することをお勧めします (当然、データベースに応じてプロパティを変更します)。
LaravelArdentArdentArdent::configureAsExternal(array( 'driver' => 'mysql', 'host' => 'localhost', 'port' => 3306, 'database' => 'my_system', 'username' => 'myself', 'パスワード' => 'h4ckr'、'文字セット' => 'utf8'、 '照合' => 'utf8_unicode_ci'), 'en'); //英語はデフォルトのメッセージ言語です。空のままでも構いません
導入
はじめる
Ardent を使用した簡単な検証
検証エラーの取得
検証の上書き
カスタム検証エラーメッセージ
カスタム検証ルール
モデルフック
関係のより明確な定義
熱心なエンティティを自動的に水分補給します
冗長なフォームデータを自動的に削除する
セキュアテキスト属性を自動的に変換する
独自のルールによるアップデート
構築するアプリケーションで同じ定型コードを再作成する頻度はどのくらいですか?この典型的なフォーム処理コードに見覚えがあるでしょうか?
Route::post('register', function() {$rules = array('name' => '必須|間:3,80|alpha_dash','email' => '必須|間:5,64|メール|unique:users','password' => 'required|min:6|confirmed','password_confirmation' => 'required|min:6');$validator = Validator::make(Input::all(), $rules);if ($validator->passes()) { User::create(array('name' => Input::get('name'),'email' => Input::get('email'),'password' => Hash::make(Input:: get('パスワード')) ));return Redirect::to('/')->with('message', 'ご登録いただきありがとうございます!'); else {return Redirect::to('/')->withErrors($validator->getMessages()); } } );
これを自分で実装すると、多くの場合、定型コードが繰り返されることになります。さらに、コントローラー (またはルート ハンドラー) が早期に太くなり、コードが乱雑で醜くなり、理解しにくくなります。
他の誰かがあなたの代わりに面倒な仕事をすべてやってくれたらどうしますか?上記の混乱を吐き出す代わりに、入力する必要があるのがこれらの数行だけだったらどうでしょうか?...
Route::post('register', function() {$user = 新しいユーザー;if ($user->save()) {return Redirect::to('/')->with('message', 'Thanks登録してください!'); else {return Redirect::to('/')->withErrors($user->errors()); } } );
アーデント登場!
Ardent - 魔法のダストを動力源とし、手首に優しい、退屈な入力サニタイズ定型文をすべて解決するワンストップ ソリューションです。
冗談はさておき、入力検証機能は、作成と保守がすぐに面倒になってしまいます。 Ardent は、多くの反復的なタスクを自動化するためのヘルパーを提供することで、これらの複雑さを解消します。
ただし、Ardent は入力検証に優れているだけではなく、Eloquent データ モデル コードを大幅に削減するのに役立ちます。 Ardent は、複数の個別のアプリケーションで非常に似たコードを何度も書くのにうんざりしている場合に特に役立ちます。
たとえば、ユーザー登録やブログ投稿の送信は、あるアプリケーションで実装し、他のアプリケーションで再利用する必要がある一般的なコーディング要件です。 Ardent を使用すると、自己認識型のスマートモデルを 1 回作成するだけで、他のプロジェクトで (まったくまたはほとんど変更せずに) 再利用できます。このやり方に慣れてしまうと、Ardent なしでどうやってやっていたのかと正直不思議に思うでしょう。
脳疲労による損傷を繰り返す必要はもうありません。
Ardent
コア機能を変更することなくEloquent
基本クラスを拡張することを目指しています。 Ardent
自体はIlluminateDatabaseEloquentModel
の子孫であるため、すべてのArdent
モデルはEloquent
と完全に互換性があり、Laravel の素晴らしい OR/M のパワーを最大限に活用できます。
新しい Ardent モデルを作成するには、モデル クラスをArdent
基本クラスから派生させるだけです。次の例では、例をわかりやすくするために完全な名前空間クラスを使用しますが、すべてのクラスでuse
ことをお勧めします。
use LaravelArdentArdentArdent;class ユーザーは Ardent {} を拡張します
注:プレーンバニラの Eloquent モデルと Ardent の子孫を自由に組み合わせることができます。モデル オブジェクトがユーザーが送信したコンテンツに依存しないため、検証が必要ない場合は、Eloquent モデル クラスをそのままにしておくことができます。
Ardent モデルは、Laravel の組み込み Validator クラスを使用します。モデルの検証ルールの定義は簡単で、通常はモデル クラスで静的変数として行われます。
class User extends LaravelArdentArdentArdent { public static $rules = array('name' => 'required|between:3,80|alpha_dash','email' => 'required|between:5,64|email|unique:users', 'password' => 'required|min:6|confirmed','password_confirmation' => '必須|分:6', ); }
注: 配列構文も検証ルールに自由に使用できます。古い Laravel ドキュメントのリンクを気にしないでいただければ幸いですが、Laravel ドキュメントは優れていますが、検証ルールのパイプ/配列構文に関する明確なリファレンスは残念ながら 5.1 以降なくなっています。
Ardent モデルはArdent->save()
が呼び出されたときに自動的に検証されます。
$user = 新しいユーザー;$user->name = 'John doe';$user->電子メール = '[email protected]';$user->パスワード = 'test';$success = $user->save( ); // モデルが無効な場合は false を返します
注:
Ardent->validate()
メソッドを使用していつでもモデルを検証することもできます。
Ardent モデルが検証に失敗すると、検証失敗メッセージを含むIlluminateSupportMessageBag
オブジェクトが Ardent オブジェクトにアタッチされます。
Ardent->errors()
メソッドまたはArdent->validationErrors
プロパティを使用して、検証エラー メッセージ コレクション インスタンスを取得します。
Ardent->errors()->all()
を使用してすべての検証エラーを取得します。 Ardent->validationErrors->get('attribute')
を使用して、特定の属性のエラーを取得します。
注: Ardent は、エラーをフォーマットするシンプルかつエレガントな方法を備えた Laravel の MessagesBag オブジェクトを活用しています。
Ardent の検証をオーバーライドするには 2 つの方法があります。
forceSave()
モデルを検証しますが、検証エラーがあるかどうかに関係なく保存されます。
Ardent->save($rules, $customMessages)
とArdent->validate($rules, $customMessages)
は両方とも 2 つのパラメータを取ります。
$rules
Ardent::$rules
と同じ形式の Validator ルールの配列です。
$customMessages
パラメータにも同じことが当てはまります ( Ardent::$customMessages
と同じ)
空ではない配列は、メソッドのそのインスタンスに対してのみ、クラスによって指定されたルールまたはカスタム エラー メッセージをオーバーライドします。
注:
$rules
と$customMessages
のデフォルト値は空のarray()
です。したがって、array()
渡しても何もオーバーライドされません。
Laravel Validator と同様に、Ardent では同じ構文を使用してカスタム エラー メッセージを設定できます。
class User extends LaravelArdentArdentArdent { public static $customMessages = array('required' => ':attribute フィールドは必須です。', ... ); }
Laravel Validator の場合と同じ方法でカスタム検証ルールを作成できます。
Ardent は、Eloquent のモデル イベントにいくつかの構文糖衣、つまり従来のモデル フックを提供します。これらは、モデル生活のさまざまな瞬間に追加の操作を接続する簡単な方法です。これらは、エントリを削除する前に追加のクリーンアップ作業を行ったり、検証が行われた後に自動修正を実行したり、更新が行われた後に関連モデルを更新したりするために使用できます。
すべてのフックbefore
false
(単に "falsy" 値ではなく、特にブール値) を返すと、操作が停止します。したがって、たとえば、 beforeSave
メソッドで何か問題が発生した場合に保存を停止したい場合は、 return false
だけで保存は行われません。当然、 afterSave
も呼び出されません。
利用可能なフックの完全なリストは次のとおりです。
afterCreate()
before
/ 後
before
/ afterSave()
afterUpdate()
before
/後
before
/ afterDelete()
before
/ afterValidate()
- false を返すと検証が停止するため、検証が失敗したためsave()
操作も失敗します。
たとえば、 beforeSave
使用してユーザーのパスワードをハッシュすることができます (実際には、自動ハッシュを使用することをお勧めします)。
class User extends LaravelArdentArdentArdent { public function beforeSave() {// 新しいパスワードがある場合は hash itif($this->isDirty('password')) { $this->password = Hash::make($this->password ); true を返す;//またはブール値 false のみが操作を停止するため、何も返さない } }
beforeSave
とafterSave
実行時に含めることができます。 save()
(またはforceSave()
) メソッドの引数としてモデルとともにクロージャを渡すだけです。
$user->save(array(), array(), array(), function ($model) { // beforeSaveecho のクロージャー "モデル オブジェクトを保存しています...";return true; }, function ($model) { // afterSaveecho のクロージャー "done!"; } );
注:保存されるモデルへの参照が渡されるため、クロージャには 1 つのパラメータが必要です。
メソッド名自体とほぼ同じ内容のワンライナーがすべて含まれており、クラスがいかに乱雑であるかに気づいたために、多数のリレーションを含む Eloquent モデルを作成したことがありますか?
Ardent では、関係をその情報を含む配列で明確に定義でき、メソッドで定義した場合と同様に機能します。以下に例を示します。
class User extends LaravelArdentArdentArdent { public static $relationsData = array('address' => array(self::HAS_ONE, 'Address'),'orders' => array(self::HAS_MANY, 'Order'),'groups' = > array(self::BELONGS_TO_MANY, 'グループ', 'テーブル' => 'グループを持つユーザー') ); }$user = User::find($id);echo "{$user->住所->番地}, {$user->住所->都市} - {$user->住所->州}";
配列の構文は次のとおりです。
最初のインデックス値: リレーション名。 hasOne
、 hasMany
、 belongsTo
、 belongsToMany
、 morphTo
、 morphOne
、 morphMany
、または関連定数の 1 つ (たとえばArdent::HAS_MANY
またはArdent::MORPH_ONE
)。
2 番目のインデックス: 完全な名前空間を含むクラス名。例外は、追加の引数を必要としないmorphTo
リレーションです。
名前付き引数は、元の Eloquent メソッドに定義されているものに従います。
foreignKey
[オプション]、 hasOne
、 hasMany
、 belongsTo
、 belongsToMany
に有効
table
、 otherKey
[オプション]、 timestamps
[ブール値、オプション]、およびpivotKeys
[配列、オプション]、 belongsToMany
に有効
name
、 type
、およびid
。 morphTo
、 morphOne
、およびmorphMany
によって使用されます (最後の 2 つはname
を定義する必要があります)
注:この機能は、Yii 1.1 ActiveRecord の簡単なリレーションに基づいています。
Ardent は、フォーム入力送信からエンティティ モデル クラスを自動的にハイドレートすることができます。
アクションを見てみましょう。次のコードの断片を考えてみましょう。
$user = 新しいユーザー;$user->name = 入力::get('name');$user->email = 入力::get('email');$user->password = Hash::make(Input ::get('パスワード'));$user->save();
Ardent の魔法を呼び出して、前のスニペットを書き直してみましょう。
$user = 新しいユーザー;$user->save();
それでおしまい!私たちがやったのは、退屈なものを削除したことだけです。
信じられないかもしれませんが、上記のコードは、かなり冗長ではあるものの、本質的には古いコードと同じタスクを実行します。 Ardent は、ユーザーが送信したフォーム データからの属性をモデル オブジェクトに設定します。どの Eloquent プロパティに入力し忘れたのかを見つけるのに苦労する必要はもうありません。退屈なことは Ardent に任せて、あなたは楽しいことに取り組んでください。
$fillable
/ $guarded
プロパティに応じて、内部的には同じ一括割り当てルールに従います。
自動ハイドレーション機能を有効にするには、モデル クラスで$autoHydrateEntityFromInput
インスタンス変数をtrue
に設定するだけです。ただし、既存のプロパティが入力されないようにするため、更新シナリオでも自動ハイドレーションが必要な場合は、代わりに$forceEntityHydrationFromInput
使用する必要があります。
class User extends LaravelArdentArdentArdent { public $autoHydrateEntityFromInput = true; // 新しいエントリの検証をハイドレートします public $forceEntityHydrationFromInput = true; // 検証が呼び出されるたびにハイドレートします}
Ardent モデルは、冗長な入力データ (パスワード確認、非表示の CSRF _token
、カスタム HTTP _method
フィールドなど) を自動的に魔法のように削除できるため、余分なデータがデータベースに保存されることはありません。 Ardent は確認フィールドを使用してフォーム入力を検証し、モデル インスタンスをデータベースに保存する前にこれらの属性を慎重に破棄します。
この機能を有効にするには、モデル クラスで$autoPurgeRedundantAttributes
インスタンス変数をtrue
に設定するだけです。
class User extends LaravelArdentArdentArdent { public $autoPurgeRedundantAttributes = true; }
追加のフィールドを削除することもできます。属性Ardent::$purgeFilters
は、カスタム ルールを追加できるクロージャの配列です。これらのクロージャは引数として属性キーを受け取り、パージする必要がある属性に対してfalse
返す必要があります。このような:
関数 __construct($attributes = array()) { 親::__construct($attributes); $this->purgeFilters[] = function($key) {$purge = array('tempData', 'myAttribute');return ! in_array($key, $purge); }; }
モデル クラスにpassword
という名前の属性があるが、プレーンテキスト バージョンをデータベースに保存したくないとします。実用的なのは、元のコンテンツのハッシュを保存することです。心配しないでください。Ardent は、任意の数の安全なフィールドを自動的に変換することができます。
これを行うには、モデル クラスのArdent::$passwordAttributes
静的配列変数に属性名を追加し、 $autoHashPasswordAttributes
インスタンス変数をtrue
に設定します。
class User extends LaravelArdentArdentArdent { public static $passwordAttributes = array('password'); パブリック $autoHashPasswordAttributes = true; }
Ardent は、プレーンテキストのパスワード属性を安全なハッシュ チェックサムに自動的に置き換え、データベースに保存します。 Laravel Hash::make()
メソッドを内部的に使用してハッシュを生成します。注: API などを構築している場合、パスワード (たとえハッシュ化されていても) が簡単に公開されないように、Eloquent の$hidden
属性を使用することをお勧めします :)
Ardent スタンドアロンを使用している場合は、 Ardent::$hasher
使用してUser::$hasher->check($given_password, $user->password)
のようなものを使用してフィールド値を検証できます。
Ardent は独自のアップデートをお手伝いします。 Laravel のドキュメントによると、一意のルールでフィールドを更新する (したがって検証する) 場合、更新するレコードの一意の ID を渡す必要があります。この ID を渡さないと、Laravel のバリデーターはこのレコードが重複していると判断するため、検証は失敗します。
Laravel ドキュメントから:
'電子メール' => '一意:ユーザー、電子メール、10'
以前は、プログラマーは、ID の受け渡しと、実行時に ID を含めるためのルールセットの変更を手動で管理する必要がありました。アーデントの場合はそうではありません。 unique
を使用してルールを設定し、関数updateUniques
呼び出すだけで、残りは Ardent が処理します。
拡張モデルでルールを定義します
public static $rules = array( 'email' => 'required|email|unique', 'password' => 'required|between:4,20|confirmed', 'password_confirmation' => 'between:4,20', );
コントローラーで更新する必要がある場合は、単に呼び出します
$model->updateUniques();
必要に応じて、実行時にルールをupdateUniques
に渡すことができます。それ以外の場合は、モデルによって提供される静的ルールが使用されます。
上記のルールの例では、Laravel ドキュメントで説明されているように、どのテーブルを使用するか、さらにはどのフィールドを使用するかをバリデーターに伝えていないことに注意してください (つまりunique:users,email,10
)。アーデントはそれを理解するのに十分賢い。 (github ユーザー @Sylph に感謝します)