目標を設定するとき、常に本当に必要なものを考える必要があります。 サイトのバックエンド部分の場合、これは次のとおりです。
- 最小コード、およびその結果、データの一般化
- 特定のセクションに展開可能
- サイトのフロントエンド部分とバックエンド部分の間の直接接続の欠如
最小コード
組み込みのYiiジェネレーターを使用してCRUDを生成した多くの開発者は、ほぼ同じコードが作成されることを知っていると思いますが、これは面倒でOOPの原則に少し反します。 これに加えて、CreateアクションとUpdateアクションはidが存在する場合にのみ異なる(idは新しいレコードに対してまだ作成されていない)と言えるため、Createアクションを除外できます。
データの一般化
現時点では、私が使用している唯一のデータ編集は、テーブルに書き込むためのステータス「バスケット内」です。 これについて非常に簡単に説明すると、ほとんどすべてのテーブルに、ステータスフィールド(tinyint、index)の値が0(通常)および1(リモート状態)であることがわかります。
特定のセクションに展開可能
おそらくすべてのルールには例外があり、それらのソリューションを確実に提供する必要があります。 バックエンドの場合、これは基本機能の標準動作をオーバーライドする機会です。
フロントエンドとバックエンド間の直接接続の欠如
バックエンドは追加機能であり、アプリケーションから安全に削除する必要があります。 私の場合、これは同じ名前のモジュールの簡単な削除です。
7つのステップで練習する
1.標準のGiiツールを使用して「バックエンド」モジュールを作成します(これについては詳しく説明しません。このための公式ドキュメントがあります)。
2.基本モデルを作成します。この場合、このモデルはバスケットの操作方法を知っています。
abstract class TModel extends CActiveRecord { const STATUS_DEFAULT = 0; const STATUS_REMOVED = 1; public function defaultScope() { return array( 'condition' => 'status=' . self::STATUS_DEFAULT ); } public function removed() { $this->resetScope()->getDbCriteria()->mergeWith(array( 'condition' => 'status=' . self::STATUS_REMOVED )); return $this; } public function restore() { if($this->getIsNewRecord()) throw new CDbException(Yii::t('yii','The active record cannot be deleted because it is new.')); if($this->status != self::STATUS_REMOVED) return false; $this->status = self::STATUS_DEFAULT; $this->save(false, array('status')); return true; } public function beforeDelete() { if($this->status == self::STATUS_DEFAULT) { $this->status = self::STATUS_REMOVED; $this->save(false, array('status')); return false; } return parent::beforeDelete(); } }
3. CRUDの基本コントローラーを作成します。
class BackendController extends CController { public $defaultAction = 'list'; public function actions() { return array( 'list' => 'backend.actions.ListAction', 'update' => 'backend.actions.UpdateAction', 'delete' => 'backend.actions.DeleteAction', 'restore' => 'backend.actions.RestoreAction', ); } }
4.動作するモデルとビューを「推測」する基本アクションを作成します(通常、コードについてはコメントしませんが、ここでは記事専用のコメントをいくつか作成しました)。
abstract class BackendAction extends CAction { private $_modelName; private $_view; /** * * - */ public function redirect($actionId = null) { if($actionId === null) $actionId = $this->controller->defaultAction; $this->controller->redirect(array($actionId)); } /** * . * - */ public function render($data, $return = false) { if($this->_view === null) $this->_view = $this->id; return $this->controller->render($this->_view, $data, $return); } /** * * , id */ public function getModel($scenario = 'insert') { if(($id = Yii::app()->request->getParam('id')) === null) $model = new $this->modelName($scenario); else if(($model = CActiveRecord::model($this->modelName)->resetScope()->findByPk($id)) === null) throw new CHttpException(404, Yii::t('base', 'The specified record cannot be found.')); return $model; } /** * , * - */ public function getModelName() { if($this->_modelName === null) $this->_modelName = ucfirst($this->controller->id); return $this->_modelName; } public function setView($value) { $this->_view = $value; } public function setModelName($value) { $this->_modelName = $value; } }
5.基本的なリストアクションを作成します。
class ListAction extends BackendAction { public function run($showRemoved = null) { $model = $this->getModel('search'); if($showRemoved !== null) $model->removed(); if(isset($_GET[$this->modelName])) $model->attributes = $_GET[$this->modelName]; $this->render(array( 'model' => $model, 'showRemoved' => $showRemoved, )); } }
6.基本的な更新アクションを作成します。
class UpdateAction extends BackendAction { public function run() { $model = $this->getModel(); if(isset($_POST[$this->modelName])) { $model->attributes = $_POST[$this->modelName]; if($model->save()) $this->redirect(); } $this->render(array('model' => $model)); } }
6.基本アクションの削除を作成します。
class DeleteAction extends BackendAction { public function run() { $this->getModel()->delete(); $this->redirect(); } }
7.基本的な復元アクションを作成します。
class RestoreAction extends BackendAction { public function run() { $this->getModel()->restore(); $this->redirect(); } }
確認する
上記のすべてを検証するには、モデルとArticleコントローラーを作成します。
class Article extends TModel { public static function model($className=__CLASS__) { return parent::model($className); } public function tableName() { return 'article'; } public function rules() { return array( array('name, content, createTime', 'required'), ); } } class ArticleController extends BackendController { // , }
まとめ
最も単純なケースでは、新しいCRUDを作成するには、空のコントローラーと2つのビュー(リスト、更新)を作成する必要があります。 追加の機能が必要な場合は、単に追加するか、現在の機能を書き換えてください。
ご注意
プレゼンテーションコードは、開発者ごとに一意である可能性が高く、標準のCRUDからも取得できるため、説明しません。