Post
モデルの準備ができたので、コントローラー PostController
のアクションとビューを微調整する必要があります。このセクションでは、まずCRUD操作のアクセス制御をカスタマイズし、次に create
操作と update
操作を実装するコードを変更します。
最初に行うことは、アクセス制御をカスタマイズすることです。なぜなら、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
は、必要なHTMLフォームをレンダリングするために、create
ビューと update
ビューの両方に埋め込まれた部分ビュー /wwwroot/blog/protected/views/post/_form.php
を生成します。
最初に _form.php
ファイルを変更して、HTMLフォームが title
、content
、tags
、status
の必要な入力のみを収集するようにします。最初の3つの属性の入力にはプレーンテキストフィールドを使用し、status
の入力にはドロップダウンリストを使用します。ドロップダウンリストのオプションは、投稿ステータスのテキスト表示です。
echo $form->dropDownList($model,'status',Lookup::items('PostStatus'));
上記では、Lookup::items('PostStatus')
を呼び出して、投稿ステータスのリストを取得しています。
次に、投稿がデータベースに保存される前に、いくつかの属性(例:create_time
、author_id
)を自動的に設定できるように Post
クラスを変更します。 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
テーブルを更新します。この作業は、投稿がデータベースに正常に保存された後にYiiによって自動的に呼び出される afterSave()
メソッドで行うことができます。
protected function afterSave()
{
parent::afterSave();
Tag::model()->updateFrequency($this->_oldTags, $this->tags);
}
private $_oldTags;
protected function afterFind()
{
parent::afterFind();
$this->_oldTags=$this->tags;
}
実装では、既存の投稿を更新している場合にユーザーがタグを変更したかどうかを検出するため、古いタグが何であるかを知る必要があります。このため、変数 _oldTags
に古いタグを保持するために afterFind()
メソッドも記述します。 afterFind()
メソッドは、ARレコードがデータベースのデータで設定されたときにYiiによって自動的に呼び出されます。
ここでは Tag::updateFrequency()
メソッドの詳細は説明しません。興味のある読者は、ファイル /wwwroot/yii/demos/blog/protected/models/Tag.php
を参照してください。
タイプミスを見つけた場合、またはこのページの改善が必要と思われる場合は、
githubで編集してください !
updateFrequencyとその他のタグ関数
この時点で、yii/demos/blog/protected/models/Tag.phpクラスから3つの関数を入手しない限り、デモは動作を停止します。
そちらにアクセスさせるのではなく、ここに示します。
public function updateFrequency($oldTags, $newTags) { $oldTags=self::string2array($oldTags); $newTags=self::string2array($newTags); $this->addTags(array_values(array_diff($newTags,$oldTags))); $this->removeTags(array_values(array_diff($oldTags,$newTags))); } public function addTags($tags) { $criteria=new CDbCriteria; $criteria->addInCondition('name',$tags); $this->updateCounters(array('frequency'=>1),$criteria); foreach($tags as $name) { if(!$this->exists('name=:name',array(':name'=>$name))) { $tag=new Tag; $tag->name=$name; $tag->frequency=1; $tag->save(); } } } public function removeTags($tags) { if(empty($tags)) return; $criteria=new CDbCriteria; $criteria->addInCondition('name',$tags); $this->updateCounters(array('frequency'=>-1),$criteria); $this->deleteAll('frequency<=0'); }
一般エラー 8: 読み取り専用データベース(SQLite)への書き込みが試行されました
LinuxでSQLiteを使用していて、上記のエラーが発生した場合は、.dbファイルとその親フォルダー(おそらく/ data)に権限が付与されている必要があることに注意してください。そうでない場合は、上記のエラーが発生します。
コメントするには、サインアップまたはログインしてください。