`Query` を愛用する。(もしくは `->all()` を避ける)

Posted on
ORM-and-Database

Cake2では、Modelからの返却値がすべて配列でした。
そのため、私はCake3を利用し始めた当初、「データベースからの取得した内容」は「値の集合」に変換して処理するぞ!みたいな意識が働きがちでした。
例えばこんな様子です

$books = $this->Books->find()->all();
$this->set(compact('books'));

もっと酷い時は、ResultSetの使い方に難儀してhydrationをいじって、そのまま配列にして処理を・・・という書き方をしたりもしました。

ref: Class Cake\ORM\Query | CakePHP 3.4

しかし、QueryはIteratorAggregateを備えているので、「それをそのままループさせる」ことでレコードを処理することが可能です

// in controller
$books = $this->Books->find();
$this->set(compact('books'));

// in template
<?php foreach ($books as $book): ?>
  <div><h1><?= h($book->title) ?></h1></div>
<?php endforeach; ?>}

個人的には「単純にレコードを取り出したいだけ」の時は(all()などを使って)ResultSet化しないでQueryオブジェクトのままやり取りすることが多いです。

  1. Queryのままにしておく = 結果を確定させないままの状態を維持しておくことで利用できる機能があるため
    • orderwhereの追加、subqueryの利用など
  2. 後にロジックの改修があったときに変更をしやすい
    • 1と同じ理由です
  3. 明示的にall()を使っている箇所について、必ず「ResultSetが欲しい」「DBにクエリを実行させたい」と言ったような意図をコード上で表現できるようになる
  4. 単純にコードが減る

1,2は昨日の話です。3,4は表現力の話です。
これらに鑑みて、「デメリットはあまり無さそうでちょっとメリットがあるな」というのが、現時点での私の所見です。