もろもろTips

利用する割に忘れてしまう JavaScript、CSSの$scripts_for_layoutへの出力

ビューで動的に JavaScript のプログラムや CSS のスタイルを指定する場合、body タグ内に script タグや style タグの各ブロックを挿入するのも、HTML として美しくない感じがする。ここはやはり、header タグ内に入れたい。

CakePHP 1.2 では、layout テンプレートに $scripts_for_layout を指定して、header タグ内に出力する方法が準備されている。

JavaScript プログラムであれば、Javascript ヘルパーの「$javascript->codeBlock()」メソッドを利用すればよい。あるいは、Javascript や CSS も含めて、ビューのメソッド「addScript()」を利用する方法がある。以下ビュー内での例。

例1
<?php echo $javascript->codeBlock(<<<JSPRG
$(document).ready(function() {
    $("input[type='button']").click(function() {
        $(this).parent().hide();
    });
});
JSPRG
, array('inline'=>false)) ?>

例2
<?php $this->addScript(<<<CSSTL
<style type="text/css">
.imgbox {
    float: left;
    margin: 5px;
    width: 120px;
}
</style>
CSSTL
) ?>

(090806)

利用する割に忘れてしまう指定 conditions の or 指定

Model->find() メソッドの検索条件指定で、or 検索する際の指定の仕方を忘れて頓珍漢な書き方を繰り返すので、メモしておこう。

例として、テーブル定義で「`update` date default null」と定義したカラムで、update カラムのデータが null か 0 の検索指定とする。

$data = $this->Model->find('all', array(
    'conditions' => array(
        'or' => array(array('update'=>null), array('update'=>'0000-00-00')))));

ところで、0 の指定で「’update’=>0」とすると、SQL文では「`update`=>’0’」となり検索条件が変わってしまうので、日付を扱うときは「’0000-00-00’」の方がいいようだ。

(090619)

追加情報

and と or の組合せについて、上のテーブルで「`delete` date default null」と定義されているカラムがあり、「updateがnullか0」かつ「deleteがnullか0」ならば、という条件の指定の仕方は以下の通り。

'conditions' =>array(
    'and' => array(
        array('or' => array(
            array('update'=>null), array('update'=>'0000-00-00'))
        ),
        array('or' => array(
            array('delete'=>null), array('delete'=>'0000-00-00'))
        )
    )
)

連想配列で同じキーが利用できないための処置だと思うが、チト複雑な感じ。(090620)

利用する割に忘れてしまう指定 unbindModelとpaginate

一覧表の作成で、controller->paginate() にはよくお世話になる。これで表を作成する際、不要なモデルを切り離すのに Model->unbindModel() を使うのだが、このメソッドは次の Model->find() 操作だけ有効で、その次のモデル操作ではリセットされる。

paginate() で予め unbindModel() や bindModel() を利用する場合は、指定を続けて有効にさせるための方法がある。その方法は、unbindModel() や bindModel() の2番目のパラメータに、false を指定するのである。

物覚えが悪いのか、paginate() にどんなパラメータを与えるか悩んで、時間を潰す事が多い orz

(090611)

利用する割に忘れてしまう指定 paginatorでURLに引数追加

Controller->paginate() を利用すると、ビューでページのリンクを paginator ヘルパーで簡単に作成できて、とても重宝している。

ところで一覧表を作成する際、

$this->link('お知らせ', array('action'=>'topic', 'new'));

のように、アクションにパラメータを渡して条件指定することがある。この topicビューのテンプレートで $paginator->numbers() とすると、「/controller/topic/page:2」のようになり条件指定が入らない。「/controller/topic/new /page:x」のようにするためには、

$paginator->numbers(array('url' => 'new'));

のように、option 指定する。ページの左右に previous、next も入れるなら、

$paginator->options(array('url' => 'new'));

と、予め実行しておけば、paginator の他のメソッドで指定する手間が省ける。利用する割に忘れてしまうので自分参照用に記録する。爺だよなぁ、俺 (T_T)

(090611)

取りあえずメモ

RC3を使って気付いた項目を、メモ帳代わりに書き込んでみようかと。

Viewで利用するFormヘルパー

1.$form->input() で日付を年月日の順番で、月を数字入力する

$form->input('startdate', array('dateFormat'=>'YMD', 'monthNames'=>false));

セパレータを変更する場合は、「’separator’=>’/’」などとする。「/(日本語)」もOK。

2.$form->input() で「tinyint(2)」をチェックボックスとし、ラベルを前に表示する
フラグ項目で、 0,1以外に-1を使いたかったので「tinyint(2)」とカラム定義した。ビューでチェックボックス表示したかったので、パラメータに 「’type’=>’checkbox’」を指定すると、HTML出力ではラベルとチェックボックスの前後が入れ替わってしまった。以下は、強引に 「ラベル:チェックボックス」とした例。良い方法があればご教示を m(_ _)m

$form->input('flag', array('label'=>false, 'before'=>'<label>フラグ</label>'
 , 'type'=>'checkbox'));

データ検索における関係モデルとrecursive

users、posts、commentsモデルについて

class User extends AppModel {
  var $name = 'User';
  var $hasMany = array('Post' => array('className' => 'Post',
    'foreignKey' => 'user_id'));
}

class Post extends AppModel {
  var $name = 'Post';
  var $belongsTo = array('User' => array('className' => 'User',
    'foreignKey' => 'user_id'));
  var $hasMany = array('Comment' => array('className' => 'Comment',
    'foreignKey' => 'post_id'));
}

class Comment extends AppModel {
  var $name = 'Comment';
  var $belongsTo = array('Post' => array('className' => 'Post',
    'foreignKey' => 'post_id'));
}

のような関係とする。例えば「post_id=100」のデータで、Postクラスを利用して関係データを含めて検索する場合、

$this->Post->recursive = -1;
$data = $this->Post->read(null, 100);

の実行で、postsのレコードのみ読み出す。

$data = $this->Post->read(null, 100);

の実行で、postsのレコードとusersのレコードを読み出す。

$this->Post->recursive = 1;
$data = $this->Post->read(null, 100);

の実行で、posts、users、commentsのレコードを読み出す。

さてここで、複数のpostsレコードを読み出して処理したいとする。例えば、1日のpostsデータからユーザとタイトルの一覧レコードをpostlistsテーブルに登録するとする。

// 2/25日の削除指定されていない投稿データのIDを取得する
$pids = $this->Post->find('all', array('conditions' => array(
  'created >=' => '2009-02-25', 'created <' => '2009-02-26, 'deleted' => 0),
  'fields' => array('Post.id'), 'order' => 'Post.id asc', recursive => -1));

// 投稿データを読み込み、ユーザ名とタイトルを投稿一覧データに新規登録する
foreach ($pids as $pid) {
  $post = $this->Post->read(null, $pid['Post']['id']);
  $data['Postlist']['username'] = $post['User']['username'];
  $data['Postlist']['title'] = $post['Post']['title'];
  $this->Postlist->create($data['Postlist']);
  $this->Postlist->save($data['Postlist']);
}

さて、バージョン1.2-8004で実行すると、1件目はUserデータがJOINされて取り出せるが、2件目以降はJOINされなかったため、 Userデータがセットできなかった。そこで、readメソッド実行前に「$this->Post->recursive = 0;」の代入文を明示的に追加したところ、ループで繰り返される2件目以降もbelongsToのデータを読み取るようになった。

2009-02-25
再確認はしてないので、情報が誤っているかも知れません。


コメント 停止中