前の投稿の続き
モデルの責任範囲とプロジェクトにおけるその場所
モデルはデータ構造(写真、ビデオ)の不可欠な部分でもあるため、データ操作(検索、保存、削除)および関連する静的ファイルのみを対象としています。 当然、レコードを削除するときは、それに関連付けられているメディアファイルを削除する必要があります。このため、beforeDelete()またはafterDelete()を使用すると便利です。
単純なビジネスロジックを複雑なモデルに実装できます-多くの依存関係からモデルを保存し、そこから神聖なオブジェクトを膨張させないように、サービスレイヤー(サービスレイヤー)を使用する方が良いです。
モデルには表示されません:
- HTMLレイアウト、CSS、javascript
- スーパーグローバル配列($ _GET、...)
- グローバル変数
- アクセス権の確認(この点はおそらく議論の余地がありますが、実際には、操作へのアクセス制御はコントローラーで実行する必要があることを示しています)
- Yiiでラップされていないテキスト文字列:: t()
モデルは、他のコンポーネントへの依存関係をできるだけ少なくする必要があります。そのため、モデルを移植可能にし、他のプロジェクトで使用できます。 同時に、モデルが依存するコンポーネントはセッターによって設定する必要があります(たとえば、User :: setEmailComponent( 'email'))。 User :: init()でコンポーネントを割り当てることもできますが、必ずその存在を確認してください。 コンポーネントがセカンダリで利用できない場合、モデルはノイズなしで動作する必要がありますが、コンポーネントがプライマリである場合、初期化段階で例外がスローされます。
これらのシンプルなルールにより、プログラマーチームでコードをサポートし、機能を非常に柔軟に拡張できます。
ステータスの確認
通常、検証はコントローラーとビューの両方で異なる場所で行われ、検証は次のようになります。
ただし、このチェックを行うisActive()メソッドを作成すると、特に頻繁に変更されるTKのコンテキストでは、コードの制御が強化されます。 また、異なる状態ステータスへの遷移の可能性のチェックを記述するメソッドを作成すると便利な場合があります。 たとえば、レコードのステータスが「スパム」の場合、ステータスを「アクティブ」に転送することはできませんが、ステータスを「スキャン」に転送することはできます。 このすべてのロジックをモデルにも配置することが望ましいです。 (これは、ワークフローシステムを構築するときに役立ちます)
フラグフィールドの使用
テーブルのサイズ(列数)を保存し、拡張機能をより柔軟にするために、モデルはビットフラグフィールドを使用します。
このようなフィールドは、通常、データベースでは整数型(必ずしもではありません)で表され、かなり多数のフラグに対応できます。 以前の記事でフラグフィールドについては既に言及しました。 次に、実用的なアプリケーションを示します。 (ビットマスクについて
は、この記事で詳しく説明
しています )。
例:同時に複数のフラグをユーザーに割り当てることができるユーザーモデルがあります-「ベストオーサー」、「電話確認済み」、「メール確認済み」、「モデレーター投稿のリクエストを残しました」
モデルの断片 public $flags = 0; const FLAG_CONFIRM_EMAIL = 1;
MySQLクエリでは、チェックは次の形式を取ります。
SELECT * FROM `User` WHERE STATUS & 6
この例では、
名前付きの条件グループが作成されます。これにより、次のように検索できます。
User::model()->withFlags(User::FLAG_CONFIRM_EMAIL)->findAll();
関係関係
関係関係については、
公式文書に詳しく説明されてい
ます 。
実際には、そのようなニュアンスが生じます。
- FKを使用してリレーショナル接続が正しく構築されている場合、データベースによってデータの整合性が確保されるため、すべてが明確に機能するはずです。
- リレーショナルリレーションシップがYIIのみによって構築される場合(およびFKを使用できない場合)、リレーションシップを示す変数への直接アクセスは使用しないでください。代わりにCActiveRecord :: getRelated()を使用する必要があります。
- リンクの検証(正しいID)は、検証中およびbeforeSave()ハンドラーで制御する必要があります。
- 関連データの削除は、beforeDelete()ハンドラーで実装する必要があります。
属性ビュー
HTMLコードはモデルコードに含まれている場合がありますが、そこには属していません。 属性のHTML形式のビューを表示する必要がある場合は、ウィジェットを使用するか、モデル(静的メソッドを持つクラス)のヘルパーを作成する必要があります。 以下に例を示します。
ヘルパーの例 class UserHelper{ public static function getProfileLink(User $model, $htmlOptions = array()) { return CHtml::link($model->getUserName(),$model->getProfileUrl(),$htmlOptions); } }
ウィジェットの例 class UserAvatar extends CWidget { public $emptyPhotoUrl = "/static/images/no-photo.png"; public $model; public $htmlOptions; public function run(){ $avatar = $this->emptyPhotoUrl; if($this->model->hasAvatar()) { $avatar = $this->model->getAvatarUrl(); } echo CHtml::image($avatar,$this->model->getUserName(),$this->htmlOptions); } }
ウィジェットとヘルパーはビューで使用すると便利ですが、ヘルパーはCGridViewウィジェット内で使用すると便利です。
モデルロギング
モデルをデバッグするには、特に再現が困難なエラーをキャッチするには、イベントの年表を見つけることができると便利な場合があります。
これを行うには、モデルにロギングメソッドを追加し、データで実行されたすべての操作のログ(ログファイル)を保持します。 この単純なメカニズムの実装は可能ですが、CLogRouteコンポーネントを呼び出してモデルのルートの1つを構成すると便利です。ログはデータベース(慎重に、パフォーマンスを低下させます)と単純なファイルの両方に記録できます。 また、操作を実行するためにログにユーザーデータを書き込むことも有用です。これにより、報告が簡単になります。