Skip to content

Instantly share code, notes, and snippets.

@kanonji
Last active October 11, 2015 20:38
Show Gist options
  • Save kanonji/3916139 to your computer and use it in GitHub Desktop.
Save kanonji/3916139 to your computer and use it in GitHub Desktop.
CakePHP1系からブランクありでCakePHP2を使っていて思ったこと。主にディス

主観だからね。

Cookbookが分かりにくく、書いてあって欲しいことが書いてない。

章の構成

Cookbookすごく分かりにくい。章の構成はそのまま目次というか、左側のメニューになる。どのフレームワークでも同じだと思うけど、この構成が分かりにくい。探したい事を探しにくい。 「入門」の次が「ブログチュートリアル」「ブログチュートリアル - レイヤーの追加」と続いている。 チュートリアルは必要だけど、入門からの流れで順を追っていく読み物的な構成よりも、別個で読んでそこだけちゃんと分かる構成のほうが、フレームワークには必要だと思う。 あと意味がわからないのが「チュートリアルと例」内にも「ブログチュートリアル」「ブログチュートリアル - レイヤーの追加」がある。ダブってる。

ドキュメントの書かれ方が文章的過ぎる

http://book.cakephp.org/2.0/ja/models/saving-your-data.html#hasone-hasmany-belongsto 関連データを保存する(hasOne, hasMany, belongsTo)

の項目なのに

上記のような名前の付け方は、hasManyアソシエーションの場合です。hasOneの場合は、ModelName.fieldNameという名前を付けます。

hasManyの場合の例が載っている。 ちなみに、次の項目は「hasManyを保存する」なのに・・・

この辺からも、文章的に書いている感じがする。 フレームワークのドキュメントとしては、文章よりも、項目毎にサンプルと説明が同じフォーマットで淡々と載ってるほうがいい。

  • hasOne
    • FormHelperの書き方
    • サブミットされるデータ
    • save() or saveAll()のサンプル
    • 得られる戻り値
  • hasMany
    • FormHelperの書き方
    • サブミットされるデータ
    • save() or saveAll()のサンプル
    • 得られる戻り値
  • belongsTo
    • FormHelperの書き方
    • サブミットされるデータ
    • save() or saveAll()のサンプル
    • 得られる戻り値
  • HABTM
    • FormHelperの書き方
    • サブミットされるデータ
    • save() or saveAll()のサンプル
    • 得られる戻り値

もう文章の流れとかどうでもいいから、これが漏れなく書いてあるだけでどんなに分かりやすいか。 逆に文章でだらだら書かれると、重要な事は見落とすし、後であの辺に書いてあったはずと思って見直そうとしても、なかなかその箇所を見つけられない。

書いてて欲しい事は書いてない

文章は多いくせに、Model::save()の特殊な戻り値とその理由は背景とかは書いてない。 Model::save()は、成功時に$this->dataを返す。どういう状況で起こりえるか良く分からないが、$this->dataがempty()な時、trueを返す。失敗するとfalseを返す。$this->dataなんて返さずtrue/falseだけ返すなら、明確で理解しやすいのに、$this->dataなんて返すから、$this->dataとtrueはどういう違いあって、trueが帰ってきたときって成功って判断していいのか、この戻り値をどう扱えば適切なのか、いろんな疑問が出てきてしまう。でも、戻り値についてはないも書いてない。CookbookのほかのドキュメントはAPIリファレンスだけど、DocBlockから生成だから、実質ソースコード。Cookbookに書いてないからソースコード読んで察するしかない。

CakePHPって結講日本語の情報量が多いイメージがあったけど、クラスやそのメソッドとかの解説をまとめたページ、いわゆる関数リファレンスみたいなのがないから苦労してる

そもそもCookbookに書いてないこと多い。

日本語のCookbookで探してなく、英語のCookbookにも書いてなくて、CakePHP辞典を読んでみたら、その機能の章の冒頭に書いてあったりする。CakePHP辞典は、書いてあってほしい事を書いてあることが多いと思う。ただ、メソッド単位になってくると、一言しか書いてなかったりするので、完璧じゃない。

save()とsaveAll()/saveAssociated()/saveMany()の戻り値そろえて欲しい

save()は$this->dataを返すことがあるので、データを書き込む > そのデータを受け取れる。 saveAll()系は書けたか書けなかったかのtrue or falseで、保存したデータが何かは別途なんとかする。 この違いがCookbookに分かりやすく書いてないので、慣れてない人はsave()と同じ感覚でsaveAll()使って、はまる。 なにか理由があってこうなっているのかもしれないけど、理由が説明されないので、はまるといやになる。

学習コストが高い

前述のCookbookの不満によるところも大きいけど、割と学習コストが高いと思う。CakePHP 1.3系を使ったことがあって1年ちょいブランクあって2系を使い出して、かなりはまる。うまく説明できないけど、暗黙的な動きが多いのかなって思っている。 前述の通りソースコード読まないと分からないこと多いし。

特殊な例では、JsonViewを使ったら、エラー発生時{code: 500}と、HTTPステータスコード付きでJSONでエラーなレスポンスしてたから、なるほどと思っていたら、デバッグレベルを0にしたらcodeというキーがJSONから消えた。こういうの、1回はまらないと分からない。

テーブルに変更があると非常に面倒

Bakeしたファイルに書いていくので、テーブル変更からのBakeし直しをすると、自分のコードを消してしまう。かといって、最初だけBakeするのにアソシエーションの変更とかは自分で書かないといけないのもめんどくさい。アソシエーション部分だけBakeするとか、せめてファイル書き出さなくても、アソシエーション部分のコードを出力する機能が欲しい。もしくは、usersテーブルに対しAppUserというモデル名で生成してくれれば、継承がつかえたんだけど・・・

Viewも生成してくれるのは便利だけど、テーブルに変更あるとBakeし直さないといけないケースがあり、既にコードが入ってたりするととても面倒になる。

ある程度テーブルが固まってからなら、楽に開発出来ると思うけど、テーブル設計適当で、作りながらというのは、CakePHPには合わないと思う。

思いついたら追記する

コンポーネント、ビヘイビアに機能を集中させた方がいい気がする。

users pluginは、コントローラーとモデルにコードが集中しています。簡易のダッシュボード的ページや、管理画面的なものもあり、設置してコードを変えずにusers pluginが持つ機能だけを、とりあえず動かすには簡単です。

That it works out of the box does not mean it is thought to be used exactly like it is but to provide you a kick start. You will have to extend the plugin on app level to customize it.

でもREADMEには、カスタマイズして使う事が前提のような事がかいてあります。ユーザー登録時の確認メールとか、パスワードリマインダー等、ユーザー登録に欲しい機能も実装済みなので、便利ではあるんだけど、コントローラー・モデルにコードが固まってるので、users pluginの欲しい機能だけ使うというのがやりにくい。 継承でカスタマイズするのは、機能を増やすにはいいけど、減らすのはやりにくいし、とある機能を動かなくするために、メソッドをオーバーライドして、内容をコピペしたうえで1行かえるみたいな事が必要になったりする。 自分の場合は、結構な数のメソッドがそうなりそうだったで、途中で継承をやめて、ユーザーランドに全コピペしてから改造した。 もうちょっと、メソッド間の関わりを薄くして、コンポーネント・ビヘイビアにコードを置いて、選んで使う構成に出来ないだろうか?

AuthComponent::password()を使っていない

https://github.com/CakeDC/users/blob/a1f2bcf3b39f4e7aaca01e4709b975ab5927816a/Model/User.php#L573

たまたまAuthComponentnのデフォルトと同じだからいいけど、AuthComponent::password()をオーバーライドしたら、ログインとか出来なくなりそう。

Remember Me機能でusersテーブルpasswordカラムの値をCookieに焼いてる

https://github.com/CakeDC/users/blob/a1f2bcf3b39f4e7aaca01e4709b975ab5927816a/Controller/UsersController.php#L670

shaのhashだからといって、それをCookieに焼くのはまずいと思う。

Dashboard機能がおまけ

https://github.com/CakeDC/users/blob/a1f2bcf3b39f4e7aaca01e4709b975ab5927816a/Controller/UserDetailsController.php#L46

	public function index() {
		$user_details = $this->UserDetail->find('all', array(
			'contain' => array(),
			'conditions' => array(
				'UserDetail.user_id' => $this->Auth->user('id'),
				'UserDetail.field LIKE' => 'user.%'),
			'order' => 'UserDetail.position DESC'));
		$this->set('user_details', $user_details);
	}

おそらくプロフィールとか、ユーザーページとかのDashboard機能は、fieldというカラムに、user.nickname user.age みたいなフィールドを定義させるという、RDBとしては悪手な作りになっている。見ての通りLIKEが使われている。 作るアプリによって、定義したいカラムに違いがありすぎるのは確かだけど、これだと実際には使いにくすぎるので、むしろ邪魔なコードになってしまう。サンプルコードとしてはありかもしれないので、サンプルコードとして置いてあればよかったのに。

Cookbookはこんな疑問に答えてくれない

HABTAMに使う関係テーブルの構造(スキーマ)はどうだったっけ?

idという主キーが必要なのかとか、created, modifiedは使えるんだっけとか、基本的なところだけど迷った時にCookbookを見に行くと、どこに書いてありそうなのか分かりにくし、実際にHABTMの箇所にはあまり具体的には書いてない。

###Viewファイルへの値の渡り方。特にFormHelperとの連動はどうなってるんだっけ?

$this->set('foo', $value);
<?php echo h($foo);

この様にコントローラーでset()したら、Viewファイルではグローバル変数(本当にグローバル変数かは分からないけど)となっています。これはまだいいんですが、FormHelperの所が分かりません。

$this->set('users', $this->User->find('list'));
<?php $form->input('user_id');

こうすると、Viewではusersを書いてないのに連動するけど、分かりにくい。Bakeしたら動く状態のファイルが出来上がるし、それ見たらコントローラーでset()してるのを単数系にして_idを付けたのを$form->input()に渡すと連動するってことは、想像は出来るけどBakeしてない時に、どう書くんだっけと疑問に思ったら、はまってしまう。 Cookbookはこれに答えてくれない。もしかしたら、どこかに書いてあるのかもしれないけど、素早くそこにアクセス出来ない。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment