ドキュメントは実装に追いついていてほしい、という話

公式ドキュメントを参考にしてコードを書いたら、deprecated の Notice が大量に出た。

これは、

- ドキュメントには、それを知りうるように書いてあったか
- いつからこうなっていたか
- どうすればよいのか

を追いかけた記録である。

## ことの始まり

ドキュメントを見ながら CakePHP 4.4 を利用したコードを書き始めた。

``` PHP
if (!$query->isEmpty()) {
  // ～～
}
```

しかし、デバッグのためにログを見たところ deprecated の Notice が大量に出ていてエラーが埋もれていた。これではデバッグどころではない。
このコードはドキュメントを見ながら書いたはずなのに、一体どういうことなんだろうか。

## ドキュメントを確認

私が見たはずの、データ取得のドキュメントを再度確認してみた。

### 日本語のドキュメント（4.x）
[Document 4.x (ja)](https://book.cakephp.org/4/ja/orm/retrieving-data-and-resultsets.html#query-resultset) [2023-10-22 閲覧]
``` PHP
// クエリーをチェックします
$query->isEmpty();

// 結果をチェックします
$results = $query->all();
$results->isEmpty();
```

確かに私はこれを見て書いた。では英語のドキュメントはどうなっているだろう。

### 英語のドキュメント（4.x）
[Document 4.x (en)](https://book.cakephp.org/4/en/orm/retrieving-data-and-resultsets.html#checking-if-a-query-or-resultset-is-empty) [2023-10-22 閲覧]

``` PHP
// Check a query.
$query->isEmpty();

// Check results
$results = $query->all();
$results->isEmpty();
```

こちらも `$query->isEmpty();` を使うように書いてある。

CakePHP 4.4 で deprecated が出るということは、最近出たという CakePHP 5.x ではこの書き方が廃止されているかもしれない。そのドキュメントがどうなっているか確認してみる。

### 日本語ドキュメント（5.x）
[Document 5.x (ja)](https://book.cakephp.org/5/ja/orm/retrieving-data-and-resultsets.html#query-resultset) [2023-10-22 閲覧]

``` PHP
// クエリーをチェックします
$query->isEmpty();

// 結果をチェックします
$results = $query->all();
$results->isEmpty();
```

同じだ。では英語ではどうだろう？

### 英語ドキュメント（5.x）
[Document 5.x (ja)](https://book.cakephp.org/5/en/orm/retrieving-data-and-resultsets.html#checking-if-a-resultset-is-empty) [2023-10-22 閲覧]
```
// Check results
$results = $query->all();
$results->isEmpty();
```

英語はでは変わっている。

### データ取得のドキュメントのまとめ [2023-10-22 時点]
|      | 日本語ドキュメント | 英語ドキュメント |
|------|--------------------|------------------|
| 4.x  | [古い](https://github.com/cakephp/docs/blob/86625900c44871a1c1a1d51ca9023406d57ea7e7/ja/orm/retrieving-data-and-resultsets.rst) | [古い](https://github.com/cakephp/docs/blob/86625900c44871a1c1a1d51ca9023406d57ea7e7/en/orm/retrieving-data-and-resultsets.rst)   |
| 5.x  | [古い](https://github.com/cakephp/docs/blob/c20d6ff1f8522d56f1c339ac14666fea1fa71a78/ja/orm/retrieving-data-and-resultsets.rst) | [新しい](https://github.com/cakephp/docs/blob/c20d6ff1f8522d56f1c339ac14666fea1fa71a78/en/orm/retrieving-data-and-resultsets.rst)   |

### 移行ガイドの記述

CakePHP [4.3 移行ガイド](https://book.cakephp.org/4/ja/appendices/4-3-migration-guide.html) には、このような記述がある。

> クエリをプロキシするすべての ResultSetInterface メソッド（ `CollectionInterface` を含む） （これらは強制的に結果を取得し、その結果に対してプロキシされたメソッドを呼び出します）は非推奨になりました。 非推奨な使い方の例として、 `$query->combine('id', 'title');` があります。 これを `$query->all()->combine('id', 'title');` に変更する必要があります。

このドキュメントを読んで isEmpty() が該当するかどうか判るには、isEmpty() が Query オブジェクトのメソッドではなく ResultSet のメソッドであることを知っていなければならない。私がこれ（4.3 にこの記述があること）を見つけられたのはそのことを知っていたからではなく、[ソースの変更](https://github.com/cakephp/cakephp/pull/15633/commits/392ac2c6df596280641de58d082586a01ecb1de2)を追いかけたところ 4.3.0RC という文字があったからである。

## いつからこうなった？

- [2015-03-23] CakePHP 3.0 リリース
  - [3.x のドキュメント](https://book.cakephp.org/3/en/orm/retrieving-data-and-resultsets.html#checking-if-a-query-or-resultset-is-empty)でも $query から isEmpty() を呼ぶコードがあるので、3.0 からこのように書けるようだ。
- [2021-07-07] deprecated の Notice を出すソースの変更は[ここ](https://github.com/cakephp/cakephp/pull/15633)で行われた
- [2021-10-24] CakePHP 4.3 リリース
  - deprecated の Notice が出るようになる
  - ドキュメントの移行ガイドには記述がある
  - ドキュメントのサンプルは古いまま
- [2023-01-25] CakePHP 5.x のドキュメント（英語のみ）が[更新](https://github.com/cakephp/docs/pull/7579)された。
- [2023-09-10] CakePHP 5.0.0 リリース
  - 本当に削除されたのかどうかは、試していないのでわからない。
  - ドキュメントのサンプルは、英語は改訂されているが日本語のは古いまま

## どうなっていてほしいか

CakePHP 3.x のドキュメントには[このような](https://book.cakephp.org/3/ja/orm/retrieving-data-and-resultsets.html#custom-find-methods)書き方をしているところがある。

``` PHP
// コントローラーやテーブルのメソッド内で
// Prior to 3.6 use TableRegistry::get('Articles')
$articles = TableRegistry::getTableLocator()->get('Articles');
$query = $articles->find('ownedBy', ['user' => $userEntity]);
```

このようにどちらの書き方も紹介されていれば、メジャーバージョン内で変化があっても理解することができる。

## Pull Request を出してみた

自分で直せるのが OSS だし、言い出しっぺの法則というものがあるし、ただ文句をたれるだけでは生産性がない。
そこで、マージされるかわからないが Pull Request を出してみた。

- https://github.com/cakephp/docs/pull/7755
- https://github.com/cakephp/docs/pull/7756

### Pull Request がマージされた（2023/10/28 追記）

- [5.x 日本語](https://book.cakephp.org/5/ja/orm/retrieving-data-and-resultsets.html#id18)
- [4.x 英語](https://book.cakephp.org/4/en/orm/retrieving-data-and-resultsets.html#checking-if-a-query-or-resultset-is-empty)
- [4.x 日本語](https://book.cakephp.org/4/ja/orm/retrieving-data-and-resultsets.html#query-resultset)

これでわかりやすくなったことだろう。