menu
書いてる野郎
orebike@gmail.com
条件指定の1件引きはfind-first。これが基本。
$result = $this->find('first', array('conditions' => array('Hoge.id' => 123, 'Hoge.deleted' => null)));
リターンは連想配列でテーブル名のキーの下にさらに連想配列で
$result = array( "Hoge" => array( "id" => 123, "name" => "ほげ", "age" => 32, "deleted" => null ); );
みたいな形になる。
合致するレコードが無いならばfalseが戻る(nullではない)
条件指定の複数引きはfind-first。これが基本。
$result = $this->find('all', array('conditions' => array('Hoge.deleted' => null)));
返却の値はfind-allのパターン
順番を指定したい場合は orderというオプションを渡してやる
$result = $this->find("all", array("conditions" => array("Hoge.deleted" => null), "order" => array("Hoge.created DESC", "Hoge.id ASC")));
SQL同様優先度順に書く
通常は結合はアソシエーションで処理すればいいのだが、キーの制約やいろいろでできない場合がある。 PK絡みの結合しかできないからそれ以外のときはどうすればいい?joinsを使ってやろう。
$result = $this->find("first", array("fields" => array("Hoge.*","Piyo.*","Fuga.*"), "conditions" => array("Hoge.id" => 123, "Hoge.deleted" => null), "joins" => array( array("type" => "LEFT", "table" => "piyos", "alias" => "Piyo", "conditions" => "Hoge.name = Piyo.name"), array("type" => "LEFT", "table" => "fugas", "alias" => "Fuga", "conditions" => "Hoge.age = Fuga.age") )));
↑のようになる。
まず基本となるモデルのfindから始める。 そしてfields指定。通常はいらないのだが、joinsを使った場合fieldsを省略するとfindを使っている基本のモデルのフィールドしか結果に出てこない。 なのでfieldsを明示的に指定してやる必要がある。
そしておなじみコンディション。
次にjoinsここで他のテーブルとの結合条件を指定してやるSQLなら「LEFT JOIN ON」にあたる部分を書く。joinsに結合条件をを「連想配列の配列」でわたしてやる。なぜかここ普通に単体の連想配列でパラメータを渡してもぶっ壊れたSQLは生成されるが、別にPHP的には普通に動いてしまうので注意。
typeで結合方式を指定する。大体の場合は「LEFT」だろう、次に結合先のテーブル名。次がaliasでSQLならテーブルに「AS」で付ける別名にあたる。ここを対応するモデル名にしておくと後々嬉しい。
そして最後に「ON」にあたるconditionsを書いて終了。
配列でこの条件をズラズラ書けば何個でもテーブルを結合できる。
結果はというとallやfirstに準拠する。aliasを指定したので
$result = array( "Hoge" => array( "id" => 123, "name" => "ほげ", "age" => 32 ), "Piyo" => array( "name" => "ほげ", "memo" => "ゲゲゲ" ), "Fuga" => array( "age" => 32, "birth" => "2011-11-11 11:11:11" ) );
のようにアソシエーションでとってきたみたいになって非常に嬉しい。
findのoptionでconditionsと同階層に、「limit」と「page」というオプションが取れる。両方取れる値は数値でlimitが1ページあたりの最大件数、pageがページ数を表す。一番最初のページが1となっている。
どっちのパラメータもnullも取ることができて、null指定なら全件ということになる。
find-firstした結果の値は↓のようにモデル名をキーにした連想配列でリターンされる
array( 'Hoge' => array( 'id' => 1, 'piyo_name' => 'うんこ', 'created' => '2011-08-11 12:13:54', ) );
find-firstの結果件数がゼロの場合はnullではなく厳密にfalseが返るようになっている。PHP文脈では同じように扱われることが多いのであまりきにならないかもしれないが使い方を考えると知っておいたほうがいい。
find-allした結果の値は↓のようにモデル名をキーにした連想配列の配列でリターンされる
array( array( 'Hoge' => array( 'id' => 1, 'piyo_name' => 'うんこ', 'created' => '2011-08-11 12:13:54' ) ) array( 'Hoge' => array( 'id' => 2, 'piyo_name' => 'うんこさん', 'created' => '2011-08-11 12:13:55' ) ) );
結果がゼロの場合はfirstとは違い、空配列が戻るようになっている。
queryの場合はASしたテーブル名をキーにした連想配列の中にASしたカラム名をキーにした値が詰まった連想配列の配列で返ってくる。
count等のメソッドを使って出力のカラムを増やした場合はテーブル名ではなく'0'というキーの要素の連想配列に格納される。
findの形式は1個の連想配列にいモデル名のキーにフィールド名の連想配列がくっついている形式になっている。 この一番上位のモデル名は邪魔といえば邪魔なのだがモデルではこのfindの出力を死守しておいたほうがいよい。
逆に言うとこの形式をリターンしないメソッドはfindを名乗ってはダメだと思う。
リターンが連想配列なのでモデルはほっておくと自由になんでもリターンするようになってしまう。 それはそのうちviewが要求する形をリターンするに至る。
そうするとせっかく3層分離してるのに結局1直線につながってしまうのだ。モデルのview依存があがってしまってさいりようせいが落ちるのでfind形式は死守しよう。
findされた結果の値というのは連想配列とか連想配列の配列とかになって戻ってくる。railsのようにメソッドまで装備したオブジェクトとしては戻ってこない。
MySQL | CakePHP |
---|---|
integer | 数値っぽい文字列 |
datetime | yyyy-mm-dd hh:mm:ssの時刻っぽい文字列 |