Yii経験の交換:モデル(終了)



前の投稿の続き



モデルの責任範囲とプロジェクトにおけるその場所


モデルはデータ構造(写真、ビデオ)の不可欠な部分でもあるため、データ操作(検索、保存、削除)および関連する静的ファイルのみを対象としています。 当然、レコードを削除するときは、それに関連付けられているメディアファイルを削除する必要があります。このため、beforeDelete()またはafterDelete()を使用すると便利です。

単純なビジネスロジックを複雑なモデルに実装できます-多くの依存関係からモデルを保存し、そこから神聖なオブジェクトを膨張させないように、サービスレイヤー(サービスレイヤー)を使用する方が良いです。

モデルには表示されません:



モデルは、他のコンポーネントへの依存関係をできるだけ少なくする必要があります。そのため、モデルを移植可能にし、他のプロジェクトで使用できます。 同時に、モデルが依存するコンポーネントはセッターによって設定する必要があります(たとえば、User :: setEmailComponent( 'email'))。 User :: init()でコンポーネントを割り当てることもできますが、必ずその存在を確認してください。 コンポーネントがセカンダリで利用できない場合、モデルはノイズなしで動作する必要がありますが、コンポーネントがプライマリである場合、初期化段階で例外がスローされます。

これらのシンプルなルールにより、プログラマーチームでコードをサポートし、機能を非常に柔軟に拡張できます。



ステータスの確認


通常、検証はコントローラーとビューの両方で異なる場所で行われ、検証は次のようになります。



//   if($model->status == 1){ ... } //    if($model->getStatus() === Model::STATUS_ACTIVE){ ... } //   if($model->status !== 1 && $model->status !== 2 && $model->status !== 4){ ... } //--   
      
      







ただし、このチェックを行うisActive()メソッドを作成すると、特に頻繁に変更されるTKのコンテキストでは、コードの制御が強化されます。 また、異なる状態ステータスへの遷移の可能性のチェックを記述するメソッドを作成すると便利な場合があります。 たとえば、レコードのステータスが「スパム」の場合、ステータスを「アクティブ」に転送することはできませんが、ステータスを「スキャン」に転送することはできます。 このすべてのロジックをモデルにも配置することが望ましいです。 (これは、ワークフローシステムを構築するときに役立ちます)



フラグフィールドの使用


テーブルのサイズ(列数)を保存し、拡張機能をより柔軟にするために、モデルはビットフラグフィールドを使用します。

このようなフィールドは、通常、データベースでは整数型(必ずしもではありません)で表され、かなり多数のフラグに対応できます。 以前の記事でフラグフィールドについては既に言及しました。 次に、実用的なアプリケーションを示します。 (ビットマスクについては、この記事で詳しく説明しています )。

例:同時に複数のフラグをユーザーに割り当てることができるユーザーモデルがあります-「ベストオーサー」、「電話確認済み」、「メール確認済み」、「モデレーター投稿のリクエストを残しました」

モデルの断片
  public $flags = 0; const FLAG_CONFIRM_EMAIL = 1; // 00000001 const FLAG_CONFIRM_PHONE = 2; // 00000010 const FLAG_BEST_AUTHOR = 4; // 00000100 const FLAG_BECOME_MODERATOR = 8; // 00001000 /** *   * @param integer $flag * @return \User */ public function setFlag($flag) { $this->flag += intval($flag); return $this; } /** *   * @param integer $flag * @return \User */ public function unsetFlag($flag) { $this->flag -= intval($flag); return $this; } /** *    * @param integer $flag * @return boolean */ public function hasFlag($flag) { return ($this->flags & intval($flag)); } /** *     * @return array */ public function getFlagsLabels(){ return array( self::FLAG_CONFIRM_EMAIL => Yii::t('User',"Email "), self::FLAG_CONFIRM_PHONE => Yii::t('User'," "), self::FLAG_BEST_AUTHOR => Yii::t('User'," "), self::FLAG_BECOME_MODERATOR => Yii::t('User',"   "), ); } /** *      * @param integer $flag * @return \User */ public function withFlags($flag=0) { $this->getDbCriteria()->mergeWith(array( 'order'=>'flags & :flag', 'params' => array(':flag' => $flag), )); return $this; }
      
      









MySQLクエリでは、チェックは次の形式を取ります。

  SELECT * FROM `User` WHERE STATUS & 6
      
      







この例では、 名前付きの条件グループが作成されます。これにより、次のように検索できます。



  User::model()->withFlags(User::FLAG_CONFIRM_EMAIL)->findAll();
      
      







関係関係


関係関係については、 公式文書に詳しく説明されています

実際には、そのようなニュアンスが生じます。





属性ビュー


HTMLコードはモデルコードに含まれている場合がありますが、そこには属していません。 属性のHTML形式のビューを表示する必要がある場合は、ウィジェットを使用するか、モデル(静的メソッドを持つクラス)のヘルパーを作成する必要があります。 以下に例を示します。



ヘルパーの例
 class UserHelper{ /** *      * @return string */ 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つを構成すると便利です。ログはデータベース(慎重に、パフォーマンスを低下させます)と単純なファイルの両方に記録できます。 また、操作を実行するためにログにユーザーデータを書き込むことも有用です。これにより、報告が簡単になります。



All Articles