Postモデルの準備ができたら、次はPostControllerのためにアクションとビューを手直しします。この節では最初にCRUD操作のアクセス制御をカスタマイズします。次にコードを修正してcreateとupdateの操作を実装します。
最初にやりたいのは、access controlのカスタマイズです。giiで生成したコードは私達の要求に合いません。
/wwwroot/blog/protected/controllers/PostController.phpファイルを開いて、accessRules()メソッドを以下のように修正します。
public function accessRules() { return array( array('allow', // allow all users to perform 'list' and 'show' actions 'actions'=>array('index', 'view'), 'users'=>array('*'), ), array('allow', // allow authenticated users to perform any action 'users'=>array('@'), ), array('deny', // deny all users 'users'=>array('*'), ), ); }
上記のルールでは、すべてのユーザーがindexとviewアクションにアクセス可能です。認証済みユーザーは、adminアクションを含め、すべてのアクションにアクセス可能です。これ以外のシナリオではアクセスが拒否されます。ここで気をつけて欲しいのは、これらのルールはここに書き並べた順番で評価されるということです。そのときの状況に最初に一致したルールによって、アクセスの可否が決まります。例えば、ユーザーがシステムオーナーで記事作成ページを訪れようとした場合、2番目のルールが一致して、ユーザーにアクセス権が与えられます。
create操作とupdate操作のカスタマイズ ¶create操作とupdate操作はよく似ています。両方とも、ユーザーの入力を得るためにHTMLフォームを表示し、入力をバリデート(検証)し、データベースに保存します。大きな違いは、update操作ではデータベースの既存のデータをあらかじめフォームにセットするという点です。このためgiiは部分的なビュー(partial view)として/wwwroot/blog/protected/views/post/_form.phpを生成し、これをcreateとupdateの両方のビューに埋め込んでHTMLフォームを表示します。
最初に_form.phpファイルを修正して、HTMLフォームで集める入力値をtitle, content, tags, statusだけにします。はじめの3つは通常のテキスト入力欄を使います。statusにはドロップダウンリストを使います。記事のステータスを表す文字列をドロップダウンリストの選択肢にします。
echo $form->dropDownList($model,'status',Lookup::items('PostStatus'));
上の例では、記事のステータス一覧を取得するために、Lookup::items('PostStatus')を呼んでいます。
次にPostクラスを修正し、記事がデータベースに保存される前にいくつかの属性(create_timeやauthor_id)が自動的にセットされるようにします。以下のようにbeforeSave()メソッドをオーバーライドします。
protected function beforeSave() { if(parent::beforeSave()) { if($this->isNewRecord) { $this->create_time=$this->update_time=time(); $this->author_id=Yii::app()->user->id; } else $this->update_time=time(); return true; } else return false; }
記事を保存するときに、タグの出現頻度の変化を反映するためにtbl_tagテーブルを更新する必要があります。この処理はafterSave()メソッドに書けばできます。このメソッドは、データベースへの記事の保存が成功した後に、Yiiから自動的に呼ばれます。
protected function afterSave() { parent::afterSave(); Tag::model()->updateFrequency($this->_oldTags, $this->tags); } private $_oldTags; protected function afterFind() { parent::afterFind(); $this->_oldTags=$this->tags; }
実装においては、ユーザーが既存の記事を更新するときにタグを変更したかどうか判定したいので、変更前のタグが何であったかを知る必要があります。このため、afterFind()メソッドを書いて、_oldTags変数に古いタグを保持するようにしました。このafterFind()メソッドは、データベースから取得したデータがARレコードに投入されるときに、Yiiから自動的に呼ばれます。
ここではTag::updateFrequency()メソッドについて詳しく説明しません。興味のある方は/wwwroot/yii/demos/blog/protected/models/Tag.phpを参照してください。
Be the first person to leave a comment
Please login to leave your comment.