モデルに関係なくSQLを発行する

2008/03/26 | cakePHP

cakePHPではモデル(データベースのテーブル)とコントローラが密接に関連している。だからコントローラでデータベース内のデータを取得する際、通常は(あらかじめどのテーブルを使うか決められた)モデルを介してデータを取得するため、モデルで指定されたデータ以外を取得しようとするとエラーになったりすることがある(単にやり方がまずいだけなのだが)。
こういうときはデータベースに直接SQLを投げるのが手っ取り早い。cakePHPらしからぬ記述にはなってしまうが、個人的にはこれで十分。ノーマルな処理はcakePHPのノーマル処理に従い、一部の例外は直接SQLを発行することで進めることにした。
データベースに直接SQLを投げる方法は以下の記述を使用する。

$db=& ConnectionManager::getDataSource(‘default’);
$result=$db->query($sql);

これ、多分第二引数でキャッシュするか否かをbool値で与えるんだろうと思う(調べるの面倒なのでこのまま続行)。

SQLを書かなくてもプログラムが書けるところがcakePHPのいいところなのだが、直接SQLを書くことができるようになることで、より幅広く使えるようになるはずだ。

直接SQLを発行してみる

2008/03/25 | cakePHP

複雑なSQLを発行したい。
そう考えると、cakePHPで持ってる機能を使うよりも直接SQLを発行したほうが早そうだ。本当はcakePHPのお作法どおりにやりたいけれど、スピード第一。まずは動かしたい。cakePHPで直接SQLを発行する方法はこんな感じ。

$this->Site->query(‘SELECT * FROM sites as Site’,false)

モデルオブジェクトにqueryメソッドでSQLを発行することができる。queryメソッドには第二引数を渡すことができる。このメソッドはデフォルトで第二引数がtrueで渡されているのだが、この値によってSQLの結果をキャッシュするかどうかを決定できるらしい。本番時はtrueでいいのだが、開発時はfalseにして、結果をキャッシュしないほうが都合がいい。

ん〜。難しい。

paginate()をカスタマイズしてみる

2008/03/24 | cakePHP

とりあえず想像だけでpaginate()を試してみることにする。

paginate($object = null, $scope = array(), $whitelist = array())

引数は3つある。しかしまだ意味がよくわからない。スクリプトを少し読んでみた限りでは・・・。

$object    //モデル名?
$scope     //where句とかorder by句?
$whitelist //わかんない

くらいは理解できた。モデル名は配列でも渡せるような感じ。ただしデフォルトがnullということは、nullで渡すと元々コントローラで指定されているモデルが渡されるのだろう(多分)。
こんな風に記述してみた。

//$this->set(‘sites’, $this->paginate());
$this->set(‘sites’, $this->paginate(NULL,array(“Site.url LIKE ‘http%’ ORDER BY Site.title DESC”)));

いちおうこれで正しく動いているように見える。しかしイマイチ美しい書き方ではないように見える。これもおいおい調べていくことにする。

createdとmodified

2008/03/23 | cakePHP

cakePHPではcreatedとmodified(またはupdated)というカラムをdatetime型で用意しておくと、データの挿入・更新時に自動で値を設定してくれる。確かバージョン1.1まではそうだった。しかし1.1と同じように1.2で設定しても値が設定されない。なぜだ!。

どうもテーブルの設定が厳密になったらしい。1.1では当該カラム名でdatetime型でありさえすればよかったのだが、1.2では以下のように設定しなくてはいけない。

カラム名:データ挿入日時はcreated、修正日時はmodifiedかupdated(1.1と同じ)
型:datetime(1.1と同じ)
NULL許可:許可(1.1では関係なかった)
デフォルト値:[空文字](1.1では関係なかった)

こんな些細なことも変わっているのかと思うと、この先が思いやられる。

標準装備のページング機能paginate()

2008/03/22 | cakePHP

とりあえず久々にcakePHPに取り組んでいるが、ぜんぜん思い出せない。1.2ベータにチャレンジしたのが無謀ともいえないではないけれど、いまさら1.1を始めるのもちょっと・・・。

基本的なところは放置して、まずはテーブルを作成してbake。出来上がったスクリプトを覗くところから始める。ここでコントローラの記述に注目。1.1のときはなかったメソッドがいきなり出てくる。

function index() {
  $this->Site->recursive = 0;
  $this->set(‘sites’, $this->paginate());
}

sitesというテーブルを作ってbakeしてみた。上記はテーブル中のデータを一覧表示させるメソッドだ。この中の最初の行は見覚えがある。

$this->Site->recursive = 0;

sitesテーブルとリレーションのあるテーブルからデータをとってくるかどうか(とってくる階層を指定)。デフォルトは関連テーブルからのデータ取得はしない設定になっている。ここは問題なし。

2行目で新メソッドが出てくる。$this->paginate()。たしか前はfindAllメソッドが呼び出されていた箇所だ。まぁ、しかしメソッド名から想像はつく。findAllにページング処理が追加されたものだ。いきなり便利になっている。すばらしい。どういう処理になっているのか詳しく知りたいわけではないが、いちおう調べてみる。継承元の以下のファイルを調べる。

cake/libs/controller/controller.php

とりあえずpaginateで検索すると変数の定義がでてきた。

var $paginate = array(‘limit’ => 20, ‘page’ => 1);

ページング関連の設定でデフォルトで1度に取得する行数を20として、ページ番号の指定がなければ1ページ目をとってくる、ということだろう。変更したければ作成したコントローラに上記の一行を書き加えて、適宜数値を変えればよさそうだ。

で、更に検索してpaginateメソッドが出てくる。どうやら以下の引数をとるようだ。

function paginate($object = null, $scope = array(), $whitelist = array()) {
  (プログラムが書かれている)
}

ここも詳しくはわからないけれど、SQLのwhere句などを記述できそうだ。今はまだサンプルが見つけられないので、自分で適宜試してみるしかなさそうだ。

ちなみにbakeしたスクリプトにウェブからアクセスして1行追加してみた。データが追加されるのは当然だけれど、createdにデータ作成日時が自動挿入されない。たしかここは何も入力しなくても勝手にやってくれるはずだったと思ったのだが・・・。

当面試行錯誤が続きそうだ。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net