Posts tagged save
[symfony] askeet 4日目
14日目です。
昨日までに作成した質問の一覧画面から質問の個別表示ページ
http://askeet/frontend_dev.php/question/show/id/1
にアクセスするとエラーになる。調べると show アクションもビューもない。
(続きを読む…)
Firefox3 インストール
5Firefox3 が公開されました。24 時間最多ダウンロードソフトとしての世界記録挑戦ということで貢献するためにも、早速ダウンロードしてインストールしてみました。
うわさ通り、表示はかなり速くなっているのが体感できます。
あと、ロケーションバーから履歴を検索できるのが便利です。
(続きを読む…)
CakePHP Ajax のフォームを作成する
5今さらなのですが CakePHP1.1 で Ajax のフォームを作成するというのをやったのでメモしておきます。
Ajax , Javascript ヘルパーを使用できるようにする
コントローラで Ajax, Javascritp ヘルパーを使用できるようにする。
var $helpers = array('Ajax', 'Javascript');
prototype.js を読み込む
webroot/js に prototype.js を配置し、ビューで読み込みます。
<?php echo $javascript->link('prototype'); ?>
ビューでフォームを作成する
今回は submit ボタンを押した後、更新中には submit ボタンを消して変わりに「更新中」というメッセージを表示し、更新終了後にメッセージをボタンの下の id=ajax_message に表示するようにしました。
<?php
$options = array(
"update" => "ajax_message",
"loading" => "Element.hide('ajax_button'); Element.show('ajax_loading');",
"complete" => "Element.show('ajax_button'); Element.hide('ajax_loading');",
);
echo $ajax->form("/controller/action/", "post", $options);
?>
<?php echo $html->input('Model/Field', array('type'=>'text')); ?><br>
<input type="submit" id="ajax_button">
<div id="ajax_loading" style="display:none;">更新中...</div>
<div id="ajax_message"></div>
$ajax->form の $options の
“update” で更新するメッセージ領域を指定し、
“loading”でアップロード中の動き、
“complete” で処理終了後の動き
を指定しています。
コントローラに Ajax で処理するアクションを作成
function action() {
$this->layout = 'ajax';
/* $this->data にフォームの内容が渡るので必要な処理を書く */
$this->Model->id = $this->data['Model']['id'];
$this->Model->saveField("Field", $this->data['Model']['Field'], true);
}
$this->layout で ‘ajax’ を指定して余計なヘッダ、フッタが出ないようにします。
Ajax で出力するビューを作成する
上のコントローラのアクションで出力するビューを作成します。
上の例では saveField でフォームから送られてきたデータを使用して更新処理しています。その結果によってメッセージを送信します。
<?php
if($msg=$error->messageFor('Model/Field')) {
echo $msg;
} else {
echo "更新しました";
}
?>
CakePHP 1.2 の deleteAll
1CakePHP 1.2 の saveAll その1
CakePHP 1.2 の saveAll その2
のエントリーを書いているときに deleteAll というメソッドがあり気になったので調べてみました。
CakePHP 1.1 で開発時に delete するときに ID を指定するしか方法がなく、ある条件でまとめて削除したいときなどは findAll してからループで delete していました。このときも条件を指定して削除する方法がないかとソースを調べたのですがありませんでした。
使い方は非常に簡単です。findAll のように条件を指定して deleteAll を実行するだけです。
$conditions = array('User.name'=>'suzuki');
if ($this->User->deleteAll($conditions)) {
$this->Session->setFlash('削除しました');
} else {
$this->Session->setFlash('削除に失敗しました');
}
実行される SQL は以下のような感じです。
SELECT `User`.`id` FROM `users` AS `User` WHERE `User`.`name` = 'suzuki' DELETE `User` FROM `users` AS `User` WHERE `User`.`id` IN (8, 10)
SELECT で条件に合う ID を抽出して WHERE IN で DELETE しています。
ただし CakePHP1.2 の削除ですが、MySQL 4.0 では SQL の DELETE 文でエラーになってしまいます。
MySQL 5.0 ではエラーにならずに削除できました。エラーになる原因は “DELETE” の後ろにテーブルのエイリアス名があるためです。
これは “cakephp1.2でのPostgreSQLエラー。” フォーラム – CakePHP Users in Japan でもあるように既に修正されているようですが、昨日 CakePHP のサイトからダウンロードした CakePHP 1.2.0.6311 beta ではまだ修正されていないようです。
CakePHP 1.2 の saveAll その2
3CakePHP 1.2 の saveAll その1 では同一モデルへの複数レコードを saveAll で保存しました。今回はアソシエーションのモデルのデータを saveAll で保存する方法です。
アソシエーションのモデルのデータを保存
モデル
user.php
< ?php
class User extends AppModel {
var $name = 'User';
var $hasMany = array('Comment');
}
?>
comment.php
< ?php
class Comment extends AppModel {
var $name = 'Comment';
var $belongsTo = array('User');
}
?>
コントローラ
users_controller.php
function add() {
if (!empty($this->data)) {
$this->cleanUpFields();
$this->User->create();
if ($this->User->saveAll($this->data)===false) {
$this->Session->setFlash('保存に失敗しました);
} else {
$this->Session->setFlash('保存しました');
}
$this->redirect(array('action'=>'index'), null, true);
}
}
ビュー
users/add.ctp
< ?php echo $form->create('User');?>
< ?php echo $form->input('User.name');?>
< ?php echo $form->input('Comment.body'); ?>
< ?php echo $form->end('Submit');?>
CakePHP 1.2 の saveAll その1 の同一モデルへの複数レコードの保存よりも使い道は多いのではないかと思います。
追記
このエントリーは CakePHP 1.2.0.6311 beta で検証しています。
CakePHP 1.2 の saveAll その1
1CakePHP 1.2 から model に saveAll メソッドが追加されました。
同一モデルへの複数データの一括保存やアソシエーションのモデルのデータの保存が saveAll でできます。
同一モデルへの複数データの保存
$data = array(
array('name'=>'tanaka'),
array('name'=>'suzuki'),
array('name'=>'yamada')
);
if ($this->User->saveAll($data)===false) {
$this->Session->setFlash('保存に失敗しました');
} else {
$this->Session->setFlash('保存しました');
}
ただβバージョンのためか、saveAll の戻り値が成功時には NULL 失敗したときには false が返って来ます。
そのために
If ($this->User->saveAll($data)) {
とやると成功の判定が正しく行えません。
CSV を読み込んでデータをインポートするようなときにいいかもしれません。
追記
このエントリーは CakePHP 1.2.0.6311 beta で検証しています。
CakePHP 環境によってデータベースを切り替える
2テストデータを入れるなどテストと環境でデータベースを切り替えたいときがあります。
CakePHP でそれをやる方法です。
モデルの $useDbConfig に app/config/database.php で定義されている $default がデフォルトで使用されます。
database.php に $test など使用したいデータベースの分だけ定義を増やし、
それをモデルで
$this->useDbConfig = 'test';
のように指定すればいいだけです。
app/app_model.php のコンストラクタで設定するのが一番簡単かもしれません。
CakePHP 環境に応じてDBの設定を変える | Shin x blog
で色々な方法が紹介されています。
“CakePHPで超簡単スケーラビリティ” フォーラム – CakePHP Users in Japan
また、この $useDbConfig を使用して
「マスターとスレーブのMYSQLサーバがあります。レプリケーション機能で、マスターからスレーブにデータが常にコピーされています。データの更新・追加はマスターに対して行い、データの検索はスレーブで、という場合にはどうすればよいでしょうか?」
というような場合のすごく簡単な方法が紹介されています。
モデルの beforeSave,afterSave,beforeDelete,afterDelete を使用してマスターとスレーブを切り替えています。
CakePHP 入力フォームで確認画面を表示する方法
3フォームを入力後、すぐに保存ではなく一度確認画面を表示させたい場合のやり方。
こちらに詳しいやり方が書いてあります。
http://www12.atwiki.jp/nezox/pages/6.html
ポイントは
- 入力フォームで
<input type="hidden" name="mode" value="confirm">
とする。
- コントローラの add アクションでバリデーションチェック後に
if (@$_POST["mode"]=="confirm") { // 確認画面を表示する $this->render('confirm'); } else { // 保存処理 if ($this->User->save($this->data)) { $this->flash('Your post has been saved.', '/users'); } } - 確認画面の view を confirm.thtml を作成
<h1>確認画面</h1> <form action="<?php echo $html->url('/users/add'); ?>" method="post"> ログインID: <?php echo $html->tagValue('Users/login_id'); ? <?php echo $html->hidden('Users/login_id', array('value'=>$html->tagValue('Users/login_id'))); ?> <input type="button" value="戻る" onclick="history.back();"> <input type="submit" value="新規登録"> </form>
