【PHP】フレームワーク CakePHP 17ホール目【v2.4】at PHP
【PHP】フレームワーク CakePHP 17ホール目【v2.4】 - 暇つぶし2ch357:340
14/05/02 00:35:18.90
>>355
本当だよ。
俺が Mark Story 氏に実際の攻撃手順を書いて送ったのが26日。
アップデートが 2.5.0-RC2 に脆弱性のアナウンスなしで反映されたのが27日。
1.3.18 と 2.4.8 にアナウンスありで反映されたのが29日。
かなり深刻な脆弱性だったからこういう日程になったんだけど、
結果的にはミスがあって 2.4.9 が出ることになった。

必ず攻撃が成功するかはサイトの作り次第だけれど、
仕事で使ってるならアップデートした方がいいよ。

358:nobodyさん
14/05/02 00:43:14.81
>>356
今回の問題は、field改ざん検知のハッシュ値が、別のurlでも使えてしまう問題。

例えばForm->textでfield1,filed2を生成しPOSTされた値を保存するaction1、
Form->textでfield1のみ生成しPOSTされた値を保存するaction2があるとする。

action2でform改ざんを行って手動でfield2を追加しPOSTする場合を考える。

一緒にPOSTされるhash値の不一致でエラーとなるのが本来の仕様。
ただし以前のバージョンだと、form改ざんと併せてhash値をaction1のものを引用すると、
エラーにならずにfiled2を上書きできてしまう。

今回の修正で他のアクションのhash値を引用することができなくなり、本来の仕様を
回避する穴がふさがった。

ちなみにhiddenの改ざんの話は、どういう意図で言ったのか俺もよく関連はわからん。

359:nobodyさん
14/05/02 00:55:27.39
>>355だけど、すまん。意味分かったかも。リリースノート読飛ばしてコミットログしかみてなかった。actionを改ざんすることでSecurtyComponentが丸ごと迂回されるのでhiddenも改ざんできるのね。いや、ソースみてないんでこれも嘘かもしれないけどw

360:340
14/05/02 00:58:57.58
>>359
そういうこと。

361:nobodyさん
14/05/02 15:48:57.61
パンくずリストを作成するHTMLヘルパーって扱いが難しいよね
階層が増えるとビューに余計なコードを書く機会が増える
だからコントローラと独自ヘルパーで何とかしているけど、
手間がかかって仕方がない。

362:nobodyさん
14/05/02 18:24:19.36
cookbookの例にあるようにTreeビヘイビアを使ってLI リストを表示したいのですが、
ビューで表示するときはヘルパーか何か作らないといけないのでしょうか?
以下のようにしたいのですが、generateTreeListでは無理です。

・My Categories
 ・Fun
  ・Sport
   ・Surfing

363:nobodyさん
14/05/02 19:10:49.13
>>362
Treeビヘイビアは不要

Model::find('threaded');
か、
Model::find('all');
したでーたを Hash::nest() で入れ子にする。

364:nobodyさん
14/05/02 20:12:03.57
>>363
すみません、そういう事ではなくて、ビューでの表示です。
ビューで>>362みたいなリスト化して出力するには、
独自のヘルパーを作らなければいけないのか?
他に方法があれば教えてくださいっと言った質問になります。

365:nobodyさん
14/05/02 20:40:21.50
無いよ。

なんでかって言うと、再帰処理したら簡単に表現できるからなぁ。

で、再帰処理するためには入れ子構造に組み直す必要があって、
そのためには >>363 に書いた通りって意味なんだが?

366:nobodyさん
14/05/02 20:42:16.77
とりあえず $Hoge->find('threaded'); で取得したデータをダンプするなりして
よく考えてみ。

367:nobodyさん
14/05/02 21:05:59.69
HtmlHelper::nestedList() ではだめなの?

368:367
14/05/02 21:46:37.32
ごめん。
HtmlHelper::nestedList() に渡すには TreeBehavior だと自力で整形しないと駄目なんだね。
CakeDC の Utils プラグインにある TreeHelper::generate() なら >>362 の要求を満たせる。

369:nobodyさん
14/05/02 21:48:33.85
>>367
HtmlHelper::nestedList() に渡すには
単純な入れ子構造にしておかないとだめ。

Model::find('threaded'); で取得したのはそのまま使えないと思う。

いったん Model::find('all'); で取得したデータを
Hash::extract() で階層を浅くして、それを
Hash::nest(); を使って組み直すなどの手間を掛けないと使えないんじゃないかな。

370:nobodyさん
14/05/02 21:49:26.87
あ、かぶった。すまん。

TreeHelper なんてあるの知らなかった。
一度見てみるわ。

371:nobodyさん
14/05/02 22:02:34.68
いえいえ。
実は俺もわりと最近知った。

372:362
14/05/02 22:29:38.32
>>365-371
皆さんありがとうございます。素直に自作ヘルパー作って
配列を再帰して表示することにします。

373:nobodyさん
14/05/08 16:22:29.68
フィールド名がemail以外の時ってemailバリデーション効かなくない?
サンプルコード漁ったらさらっと書いてあるけど動かない…

374:nobodyさん
14/05/08 17:05:11.16
>>373
$validateの配列の書き方間違ってない?

375:373
14/05/08 17:40:55.81
すまんちゃんと効いてた。これsave時にfalse返すんだな。
他のバリデーションと同様にPOST前にポップアップで教えてくれるかと思ってた。

376:nobodyさん
14/05/08 21:14:06.37
え?そんな機能あったか?

377:373
14/05/08 22:24:36.95
POST前ポップアップってこれのことね。
URLリンク(cdn-ak.f.st-hatena.com)
もしかして俺何か勘違いしてるかな…

378:nobodyさん
14/05/08 22:33:24.56
ブラウザさん

379:nobodyさん
14/05/09 00:28:49.07
ブラウザが出してるやつかな

380:nobodyさん
14/05/09 00:37:04.59
>>378-379
マジかwwChromeww本当にありがとうw

381:nobodyさん
14/05/09 04:21:32.04
HTML5の話題でひとくくりにされてる最近のブラウザの機能やね。
CakePHPもFormHelperがそのための属性を出すようになったりはしてるけど。

382:nobodyさん
14/05/09 10:16:45.79
クライアントバリデーションに任せっきりになってしまって、
悲惨なサイトが続出するような悪寒。

楽だし負荷軽減できるしで、いいことずくめなんだけど。

383:nobodyさん
14/05/09 10:59:15.63
そうだね。悪い奴がいないと助かるんだけどね。

384:nobodyさん
14/05/09 11:01:33.24
Controllerでバリデーションしなくて
Modelに移動するいい傾向になるだけでないかな?

385:nobodyさん
14/05/09 13:43:36.22
いい傾向ってなんだ?

386:nobodyさん
14/05/09 13:51:32.25
Fat Modelのことかと思われ

387:nobodyさん
14/05/09 14:56:57.61
サーバーサイドのバリデーションをしなくていいわけじゃないから、負荷軽減にならなくね?
ちゃんと機能するようにつくれば、無通信でユーザーに間違い見せれて、
使いやすくいフォームにはなると思うけど。

388:nobodyさん
14/05/09 15:49:02.85
ブラウザで弾いておいたらサーバー側での試行回数は減るだろ。
正常系の負荷はもちろん変わらんけど。

389:nobodyさん
14/05/09 18:26:07.60
初心者なんすけど
モデルの使い道がよくわかんないっす。
何から何までコントローラーで処理しちゃってモデルはスッカラカンです。
どなたかモデルの使い道というか便利さを三行で説明しなさい。

390:nobodyさん
14/05/09 18:27:49.70
>>387
HTTPの勉強をもっとしましょう。

391:nobodyさん
14/05/09 18:46:15.86
>>389
俺も初心者だからよく分かってないが、
コントローラはモデルに作ったメソッドを呼ぶだけで、
ざっくりした条件分岐のみにとどめておくと後から非常に見やすい気がする。

392:nobodyさん
14/05/09 20:58:13.09
やりすぎると Very Fat Model になってそれはそれで見難い
バランスというかセンスが問われる部分

393:nobodyさん
14/05/09 21:01:03.07
>>389
単に好みの問題だから好きにすればいいんじゃないかな
モデルはどこからでも使える上にシングルトンっぽくインスタンスが1つだけなので
共通っぽいメソッドやクラスを実装するのにも使える

394:nobodyさん
14/05/09 21:32:58.38
ああそうか、モデルはなんとなくテーブルに紐付くものみたいに思ってたが
ロジック処理だけのモデルがあっても良いよな

395:nobodyさん
14/05/10 01:47:38.21
>モデルはなんとなくテーブルに紐付く

これは常にRORと、その派生のCakePHPに対する批判として挙げられてるね。
本来のModelとは全然違うって、激怒しているブログがあちこちにある。

なお、CakePHP3では大幅に改善されるみたいです。

396:nobodyさん
14/05/10 07:20:47.11
>>388
ああ、まぁそりゃそうか。
といっても、負荷対策が必要な状況では、効果的な対策になるほどは減らないとは思うけど。

397:nobodyさん
14/05/10 10:46:10.10
Cakeはエンティティを入れるのが遅すぎた

398:nobodyさん
14/05/10 10:53:41.99
URLリンク(tech.itandi.co.jp)

1,3は同意できるところだが
2は会社のエンジニアレベルが低いとでも言いたいのか

399:nobodyさん
14/05/10 11:01:56.24
周りがCakePHPはRailsのパクリだっつーから使ってみたら
ActiveRecordの超絶劣化っぷりにびびった

Railsも似非MVC2になりがちだけどCakeはそれ以前に
オブジェクト指向設計に真っ向から喧嘩売ってるレベル

400:nobodyさん
14/05/10 12:53:17.49
そうやって批判する奴って何も具体的な事言えない奴ばかりだよな
実際どのくらいのスキルある奴なんだろう

401:nobodyさん
14/05/10 14:23:07.62
Composerは確かにほかの言語のと比べて使いにくい印象はあるけど、
git submoduleしないとパッケージのバージョンを管理できないなんて、
なに言ってるかわからないレベルなんだが。
そんなことあるんかね?

402:nobodyさん
14/05/10 15:56:06.47
お前らのMVCは間違ってる!ってRails式を散々disるスライドがあったが
ものがちゃんと作れれば別にいいわけで、正しいからどうだってのがよくわからん

403:nobodyさん
14/05/10 17:17:38.04
>>400
DBから取ってきたデータがarrayになってる部分だと思われ
Cake3でようやくオブジェクトになるようだが

404:nobodyさん
14/05/10 17:24:14.35
それよく聞くけど、オブジェクトの方が便利なん?
書き方が変わるだけのような気がするけど

405:nobodyさん
14/05/10 17:30:12.91
Cake3を少し試してみたがEntity使えるだけでも結構変わるね
特にViewがスッキリするのはもちろんだけど今までHelperやControllerに溢れがちだったロジックもEntityクラスに置けるのが結構あるしテストも楽
array+Hash・Setに比べたら開発効率やコードの読みやすさは段違いに上がる


でも2から3への移行は大変そう

406:nobodyさん
14/05/10 17:30:20.29
>>404
Modelのメソッドはすべてstaticです、なんて言ったらJavaやRubyなどのオブジェクト指向に
慣れ親しんだ人たちから見れば、なにそのふざけた設計は?とキレられるレベル

407:nobodyさん
14/05/10 17:37:51.74
オブジェクトじゃないとActiveRecordパターンとは言えないからなぁ

408:nobodyさん
14/05/10 20:22:57.11
arrayになった理由はCake1がPHP4をサポートしていたからだろうな
さすがにPHP4でオブジェクト指向にはできなかった、と

409:nobodyさん
14/05/10 23:47:42.75
PHP4懐かしいな
修飾子やら例外やらオートローダーが無いとか
参照渡ししないとクローンになるとかいろいろあるが
ActiveRecordの足かせになりそうな制約はないな

410:nobodyさん
14/05/11 13:33:38.34
最近、嫌static厨が多くて困る

411:nobodyさん
14/05/11 13:37:57.50
static に出来るものはそのほうが良いのにね。
見極めができないんかもな。

412:nobodyさん
14/05/11 15:03:25.90
「全部static」はさすがに嫌われて当然

413:nobodyさん
14/05/11 15:07:39.63
さすがにそんなヤツはおらんやろ

414:nobodyさん
14/05/11 15:08:05.37
staticとかpublicとか分別するとどんなメリットがあるの?もうおっさんだから、今だにわからない。
function hoge を _hogeにする時はあるけど。

どなたかご親切な人
わかりやすく教えてくれませんか?

415:nobodyさん
14/05/11 15:18:12.11
>>413
CakeのModelはまさに「全部static」なんだが…

416:nobodyさん
14/05/11 15:37:28.00
>>415


どこを言ってるんだろう

417:nobodyさん
14/05/11 15:40:10.91
ん、Model.phpを「static」で検索してみたけどひとつもヒットしないよ
調べたverは2.4.6
cake3ではstaticになっているってこと?言葉の使い方がヘンなだけ?

418:nobodyさん
14/05/11 18:47:27.75
>>398
> つまり結局はタイミングの問題でしかなくて、言語の優劣がどうとか、フレームワークの優劣がどうとか、といった観点は殆ど無く選びました。
つまり結局は、他に行ったから、とりあえず元鞘を叩いておくかっていう3流エンジニアの日常か

419:nobodyさん
14/05/12 01:19:34.02
>>414
それマジで質問してるならこんなところにいないで
基本的なオブジェクト指向の勉強したほうが良いよ。

420:nobodyさん
14/05/12 01:30:03.56
>>414
static のメリットをひとことで言うと、状態を持たない(状態が変化しない)
振る舞いを提供することにより、インスタンス化した場合に本来であれば考慮するべき
状態変化の副作用から開放されることではないかと。

まず間違いなく、テストは超簡単になる。

一方、アクセス修飾子のメリットはひとことで言うと
安全な設計が簡単にできるってことではないかと。
その点 CakePHP はメンバー変数の修飾子に public を使いまくってて恐ろしいほどではある。

421:nobodyさん
14/05/12 01:35:05.49
俺もstaticって使いどころがいまいちわからん。
特にphpはランタイムが短すぎて、1回しか使わないオブジェクトが多く、
staticを変に意識すると、むしろなんでもstaticでいいんじゃないかと思えてきてしまってこわい。
逆にstaticにしないと困るような事も、あんまないから、よくわからないままで結局staticは使わないという

>>414
たとえばモデルに、とある機能を作ってたら100行を超える長いメソッドになってしまい、一部を切り出したけど、
コントローラーから直接切り出したメソッドを呼ばれるのは想定外って場合に、
protectedかprivateにしておけば、呼ばれることがない。

protectedとprivateは、コントローラーやモデルを触ってるくらいなら、
正直使い分けが活きることがほとんどない気がする。
強いて例を出すと、AppController内の処理で切り出したメソッドが、ほかのコントローラーから呼ばれるのが想定外なら、
privateにしておくと呼ばれなくなる。

422:nobodyさん
14/05/12 01:45:18.99
>>421
>なんでもstaticでいいんじゃないかと

だけどオブジェクトの状態に依存しないメソッドなんて
そうそう作る機会はないと思うんだが、
もし可能なら作って問題無いと思うんだけど?
というか、むしろ作るべき。

423:nobodyさん
14/05/12 02:01:04.78
>>422
もちろん、思えてきてしまうだけで、よく考えるとダメな事がほとんどなんだけどね。
クラスやメソッドを書き始めるときに、まずこれはstaticにできるか?
と考えると、問題ないような気がしてしまうんよ。

そういえば、かなり昔だけどCakePHPを使い始める前のオレオレフレームワークでは、
データベースアクセスするとこ全部staticメソッドにしちゃってたなぁ。
いわゆるCRUDに対応したメソッドがあるだけだったし、データはオブジェクトじゃなくて連想配列だったから、
インスタンスいらないなぁと思って。
あとバリデーターもstaticメソッドだったなぁ。
バリデーションはコントローラーでやってたから、CakePHPでいうバリデーションルールの配列みたいなのは、
コントローラーに書いて、AppController的な親にvalidateメソッドを作ってた。

424:nobodyさん
14/05/12 02:19:15.31
このスレにはガチのstaticおじさんが居る気がする

425:nobodyさん
14/05/12 04:23:13.01
cakeってfindがstaticでないのが不思議でしょうがない

426:nobodyさん
14/05/12 10:30:47.47
>CakePHPのModelはまさに「全部static」

言いたいことは何となく分かる
他のフレームワークだとModelのstaticメソッドがテーブル(Repository)の操作
インスタンスメソッドがレコード(Entity)ごとの操作に対応してるのが多い

CakePHP2まではEntityがないので
そういう他のFWから入ってModelのインスタンスはEntityだろと決めつけてかかると
ModelにRepositoryの要素しかなくてfindもインスタンスメソッドという点に違和感をおぼえる

CakePHP3だとEntityクラスとTableクラスがそれぞれ用意されるからギャップが減る
クラスが分かれるからfindがインスタンスメソッドなのは変わらないけど
DDDを意識した設計で個人的には好感触


というか他のFWのstaticなfindも
RepositoryないしQueryに相当するオブジェクトのインスタンスメソッドに処理放り投げてるだけだろうし
ただ単に使い勝手とどこまでFWが暗黙的に処理するかってだけの問題な気がする

427:nobodyさん
14/05/12 10:33:48.09
>>425
状態依存しないメソッドなら問題ないけど
CakePHP の Model のオブジェクトって状態を持ってるから無理だよ。

たとえば同じPostクラスのオブジェクトが2個あったとして
$Post1->id = 1;
$Post2->id = 2;
ってした場合にメソッドが static なら破綻する。

428:nobodyさん
14/05/12 10:36:05.68
>>426
なるほど

429:nobodyさん
14/05/12 10:47:42.76
>>427
findと何か関係あるのそれ?

430:nobodyさん
14/05/12 11:14:24.54
cakeってTable Data Gatewayパターンだと考えれば普通なんだけどな

431:427
14/05/12 11:59:05.87
>>429
例えを簡単にするつもりだったが $id は関係無かったか。
要するに find が参照するプロパティのうち
状態依存のものが沢山あるってこと。

例えば
$Post1->primaryKey = sid;
$Post2->primaryKey = cid;
とか

432:nobodyさん
14/05/12 12:02:34.37 U9jrOtar
TreeBehaviorsについて質問なのですが、

moveUpやmoveDownがfalseを返してきてまったく動作しません。
発行したSQLを見ると、SELECT文ばっかりでUPDATEをやっていないように見えます。
どうやったら動かすことができるのでしょうか。

433:nobodyさん
14/05/12 12:18:35.60
>>432
スキーマ、レコード、moveUp moveDown のコード、クエリ
この辺を貼り付けてみて

434:nobodyさん
14/05/12 12:38:18.89
CakePHPって3でActiveRecordを採用するんだったよな

435:nobodyさん
14/05/12 13:15:30.27
>>433
DBやレコードはお客のやつなんでまずいんです。ごめんなさい。

スキーマにはちゃんと
parent_id, lft, righ の定義はしてあって、moveUp, moveDown以外のツリー動作は
問題なく動作しています。


public function moveup($id = null) {
   $this->Category->id = $id;
   $res = $this->Category->moveUp($this->Category->id, abs(1)) ;
debug($res);
}

436:nobodyさん
14/05/12 13:24:21.16
>>431

CakePHPのモデルが状態を持ってることが、むしろ混乱の元になってる気がするけどな。
ループ内でsaveするならcreateしろ、とか。
結局find()したら連想配列を返すし、save()だってモデルにデータ持たせたりせずsave()に引数渡すことばかりじゃない?
よく使うfindとsaveで違和感を感じるだけで、インスタンスである必要な機能もあるけど。

まぁ言いたい事はたぶん >>426 と似たようなことなんだろうけど、
ほかのフレームワークをあまり触ってないから、違和感レベルでしか語れない。

437:nobodyさん
14/05/12 13:36:54.55
>>435
じゃぁ、verify() した結果を見たらヒントがあるかも

debug($this->Category->verify());

どこかで整合性が崩れてると実行されない可能性有り。

438:nobodyさん
14/05/12 13:49:48.47
>>437
ありがとうございます。試してみました。

verify()でしばらくかかりましたが、真っ白な画面がリターンされました。
これはツリーに不整合などの異常がなかったということですよね。

439:nobodyさん
14/05/12 14:00:55.26
>>438

時間かかってなおかつ白い画面ってことはタイムアウトですね。
かなり大きいんですね。
成功すれば bool(true) が返る。

Shell でやってログに書き込んで確認してみたらいいかも。

440:nobodyさん
14/05/12 14:03:28.70
タイムアウトで白い画面って・・・もしかして本番環境・・・?

441:nobodyさん
14/05/12 14:04:31.37
TreeBehavior 適用してるテーブルに他のモデルから更新したら
整合性グチャグチャになるから注意

442:nobodyさん
14/05/12 14:10:08.15
>>439
ありがとうございます。お察しの通りノードが3万以上あるツリーなのです。
白画面はタイムアウトですか。勉強になりました。

TeraTermからサーバにログインし curl コマンドでverifyのURLにアクセスしましたが、
ブラウザから呼んだ時とは違い、瞬時にプロンプトが返ってきてしまいます。

シェルでverifyを実行とは、具体的にはどうすればいいのでしょうか?

443:nobodyさん
14/05/12 14:11:10.17
>>440
いいえ、本番のデータをまるまるコピーしてきましたが、デバッグ環境です。

444:nobodyさん
14/05/12 14:12:13.34
>>441
他のモデルからTreeを適応しているテーブルには書き込みしに行っておりません。

445:nobodyさん
14/05/12 14:13:55.11
debug=2でタイムアウトしたら

Fatal error: Maximum execution time of 30 seconds exceeded in

ってでないっけ?

446:nobodyさん
14/05/12 14:15:27.41
>>445
Configure::write('debug', 2);

でやりましたが、白画面でした。

447:nobodyさん
14/05/12 14:27:56.28
Console/commant/VerifyHogeShell.php

classVerifyHogeShell extends AppShell {

 protected function result() {
  $Hoge = ClassRegistry::init('Hoge');
  return $Hoge->verify();
 }

 public function show() {
  debug($this->result());
 }

 public function dump() {
  //!TODO ログに書き込むロジックを記述
 }

}

こんなファイルを作って

$Console/cake VerifyHoge show

とか

$Console/cake VerifyHoge dump

とか

Shell の作り方・使い方はぐぐれば幾らでも出てくる

448:nobodyさん
14/05/12 14:31:07.10
>>442
cURLからアクセスしても最大実行時間は一緒だ。
コンソールからPHPプロセスを利用しなきゃ。
php のユーザーが誰かってことが抜け落ちてる。

449:447
14/05/12 14:32:38.76
1行目ミスった

>Console/commant/VerifyHogeShell.php

Console/Command/VerifyHogeShell.php

450:nobodyさん
14/05/12 14:37:04.67
>>447
>>448
ありがとうございます!
AppShellなるクラスが用意されていたのですね。知りませんでした。
さっそく試してみます。

451:447
14/05/12 14:41:43.59
TeraTerm ってことは Windows か。
わかってるだろうけどコマンドのディレクトリセパレータは / じゃなくて \ な。

452:nobodyさん
14/05/12 15:16:40.76
>>447
>>448

verify()をShellから実行した結果、180超のエラーが出力されました。
特に多いのは index missingというやつです。
recover() で回復できますでしょうか?

453:nobodyさん
14/05/12 15:22:02.02
>>452
以前自分も同じようになったときは、
recover()で上手く言った場合とそうでない場合とがあった。

上手く行かなかったときは時間もなかったんで、
独自でスクリプト書いてで lft と rght を振り直した。

すまんが深く探ってないんで、それ以上詳しいことはよく分からん。
一度やってみろとしか言えない。

454:nobodyさん
14/05/12 15:24:38.22
あと、verify() でエラーが出たってことは
これからも同じ問題が発生するおそれがあるんで、
更新処理を全て点検したほうがいいな。

テストを良く書けているかどうかで、こういうときに大きく差が出る。

455:nobodyさん
14/05/12 15:27:51.20
Treeビヘイビアを使ってカテゴリ管理って難しいよね。
不特定多数のカテゴリを扱うとかなったら、
今回のような問題が起きてしまう可能性があるし

456:nobodyさん
14/05/12 15:28:47.24
連投すまんが、今の状態だと recover 走らせる時もめちゃくちゃ時間かかるはずだから、
必ず Shell から実行すること。
更新中にタイムアウトなんかしたら(特にMySQLのMyISAMなどは)やっかいなことになる。

457:nobodyさん
14/05/12 15:35:37.85
>>455
入れ子集合モデルは更新コストが激高だからな。
場合に応じて使い分けるしか無いと思われ。

458:nobodyさん
14/05/12 15:38:35.35
>>453-456

アドバイスありがとうございます。
>これからも同じ問題が発生するおそれがあるんで、
お客が不正に行ったデータのInsertなどが原因だった可能性もありますが、
プログラムのほうも確認しておきます。

recover()もShellから実行しました。案外完了が早かったように思います。
今2度目のverify()です。

459:nobodyさん
14/05/12 16:13:23.60
>>453
verify()でtrueが返りました!
moveUp()をあるノードで実行して結果をdebug文で出すとtrueが返りました。
しかし、treeには何の変化もなし!ノードの位置は一切変わっていません。
なぜなのでしょうか・・・。

460:459
14/05/12 16:28:51.15
連投で申し訳ありませんが、moveUp(), moveDonw()の仕様を根本的に勘違いしていました。

bookを読むと 同じ枝の中で順番を上に上げるのがmoveUp()なのですね。

僕はそもそもmoveUp()したノードは「一つ階層を上がって、今までの親ノードと同じ階層に来る」
ということを実現するものなのかと勘違いしておりました。

申し訳ありませんでした。しかしverify, recoverをshellから実行するなどの貴重な情報が得られて
感謝です。

461:nobodyさん
14/05/12 16:30:16.90
階層を変えるなら parent_id を変更する

462:nobodyさん
14/05/12 16:31:48.27
>>461
そうですよね。
しかしparent_idを手でいじって、lft, rghtがそのままで良いのかというのが気になる点です。

463:nobodyさん
14/05/12 16:32:41.62
>>460
ちょっと興味あるんだが、レコード何件あんの?

464:nobodyさん
14/05/12 16:33:45.39
>>462
>parent_idを手でいじって
ちがーーーう!
TreeBehaviorが効いてるモデルでやるんだよ!!

465:nobodyさん
14/05/12 16:38:21.01
>>463
3万件超あります。

>>464
もちろん、DBから直接parent_idを変えたりしませんよ。
CakephpのEdit画面(もちろんTreeのモデルのもの)から変えます。

466:nobodyさん
14/05/12 17:32:11.61
>>463
んん、3万件オーバーでTreeBehaviorか。。。
ブラウザからの更新はちょっとキツイかもな。

467:nobodyさん
14/05/12 17:34:01.92
>>465
>CakephpのEdit画面(もちろんTreeのモデルのもの)から変えます。

なら問題なく lft, rght 変更してくれる。
っつーか、それがTreeBehaviorの仕事だからな。

468:nobodyさん
14/05/12 17:45:37.30
改めて思うけど、カテゴリの設計って難しすぎるな

469:nobodyさん
14/05/12 17:54:12.62
>>466-468

ありがとうございます。
parent_idを変更すると、思っていた階層の移動が完了できました。ご迷惑をおかけしました。

カテゴリはこれからも増えていく可能性があるので、
このままTreeBehaviorを実装していて安全なのかちょっと心配しています。

親子関係を実現するには普通にHABTMでもいいのではないかな、と思いましたが、
設計段階でTreeの採用が決まっていたので、これで作ってしまっています。
データ件数がでかくなった今、非常にデリケートなデータ構造なんだな、と改めて認識しております。

470:nobodyさん
14/05/12 18:14:56.49
>>468
さらにそれを管理してくのが苦痛。

471:nobodyさん
14/05/12 18:30:07.53
>>469
親子関係でHABTMってどうやるんだ

472:nobodyさん
14/05/12 19:01:06.74
>>471
・categories
・articles
・category_articles(中間テーブル)

みたいなテーブルを作る

473:nobodyさん
14/05/12 19:02:02.02
ごめん。中間テーブルの名前を間違えた。
categories_articlesだったかな。

474:nobodyさん
14/05/12 19:42:05.93
>>471

Categoryモデルの中に

public $belongsTo = array('Parent' => array('className' => 'Category',));
public $hasMany = array('Children' => array('className' => 'Category'));

と二つ記述するやりかたですかね。
それを最初に思いついたのです。
しかしTreeのほうが上ではないかという意見が出たため、そっちを採用しました。

475:nobodyさん
14/05/12 19:50:22.00
>>471
だからHABTMじゃないですね。ごめんなさい。
言うならばHas Many and Belongs to Oneでしょうか。

476:nobodyさん
14/05/13 16:37:41.63
ありゃ、もう2.5.0出たのか。
なんか最近CakePHPのバージョンあがるの早い気がするけど、気のせいか?

477:nobodyさん
14/05/13 16:39:47.73
>>476
年取っただけだと思う。
時代の流れが早く感じるよな。

478:nobodyさん
14/05/13 16:44:46.95
2.6も予定されてるのかよ。
さっさと3出して、2は打ち止めでいいだろ。

479:nobodyさん
14/05/13 17:43:09.45
今のCakeって$usesに書いてあるモデルは実際使われるまで読まれないんだよね?
ということは存在する全モデルを常に書いてもいいってこと?

480:nobodyさん
14/05/13 18:12:50.09
ぜんぜん良くはねーと思うが、負荷にはならんだろうな

481:nobodyさん
14/05/13 22:34:11.52
>>479
「今の」ってバージョンいくつからそうなったの?

482:nobodyさん
14/05/13 22:43:15.01
2.x

483:nobodyさん
14/05/14 00:35:48.56
サンクス。普段は2系使ってるから特に問題ないな

484:nobodyさん
14/05/14 02:38:22.28
プログラミングするとき3行毎に動作確認しないと
不安で死ぬやつって俺だけ?

485:nobodyさん
14/05/14 04:51:26.28
3行は短すぎるが、ちゃんと小さい処理単位でメソッドを分けておけば、
まとめて動作確認してもデバッグしやすいよ。
あとはテストを書け

486:nobodyさん
14/05/14 07:02:10.89
そんなあなたにテストファースト

487:nobodyさん
14/05/14 10:05:36.21
ぶっちゃけ、テストの利点が分からないの俺だけ?

488:nobodyさん
14/05/14 10:09:17.84
さすがに君だけじゃない?

489:nobodyさん
14/05/14 11:29:01.43
最初のうちは、いまいちわからんかもね。
インターフェースのテストで、mockの使い方がわかってくるようになると、考え方が変わるかも。

490:nobodyさん
14/05/14 12:33:17.82
>>489
俺も教えて欲しいんだけど
テスト書くのが面倒
テスト自体信用できない
書いてもやっぱり最初から書きたくなる
って思ってしまうんだけどそれでも書いた方がいいと思う?

できるプログラマーの人はみんな書いてるよね。

491:nobodyさん
14/05/14 12:42:45.04
>>490
結論としては書くべきでFA
そのことがわかるには経験が必要
てことだと思う

492:nobodyさん
14/05/14 12:51:30.16
サービスが稼動を始めてから、数ヶ月経った後くらいに、
誰かのひどいコードを見つけた時、
テストを書いてあれば・・・と思うよ。

493:nobodyさん
14/05/14 13:38:02.11
view (.ctp) ファイルのテストってどうやってやるんだろう。

494:nobodyさん
14/05/14 14:02:28.89
そこまでテストする必要があるのかはよく考えたほうが良いように思えるけど、
やるならSelenium使うんじゃない?

495:nobodyさん
14/05/14 14:08:25.34
テスト=コードが正しく動作するか確かめる

ではないんだよね?これはブラウザで確認すればいいだけだし、
大体はコード書いた後に実行して確かめているだろ。

具体的にどういう場面でテストが必要になるの?

496:nobodyさん
14/05/14 17:09:00.17
ユニットテストとユーザテストごっちゃにしている時点でなんだかな。

497:nobodyさん
14/05/14 17:52:25.48
>>495
> 大体はコード書いた後に実行して確かめているだろ。

一度書き捨てて終わらせられるなら誰も書く訳がない
改修は何度も発生する=確認も同じだけ発生する=クッソ面倒
だから面倒な確認を自動化するためにテストを作るんだ

498:nobodyさん
14/05/14 20:45:44.91
というよりさ!
まずテストコードってなんなの?
console.log()とは違うの?

499:nobodyさん
14/05/14 21:02:32.76
お前のテスト(むしろconsoleデバッグ?)
→ 逐一人の手で実行して人間がブラウザやconsoleに表示された値やを見て想定したものかどうか確認する
   自動化できてない
   複数の関数やメソッドが絡むとバグの原因の特定がしづらい

他の皆の意図するテスト(単体テスト)
→ それぞれの関数やメソッドが複数の引数のパターンに対し適切な返り値を返したり
  例外やエラーを吐いたりなど仕様通りの挙動をするかを確かめるコードを書く
  検証する対象が小さいので比較的簡単に書けるし自動化も容易い
  プログラムの小さい単位の動作をあらかじめ保証しておくことで
  後の複数の関数やメソッドが絡むテストの際にもバグの原因の特定がしやすくなる


面倒だから単体テストでググれ

500:nobodyさん
14/05/14 21:19:27.30
さっぱり意味が分からん

501:nobodyさん
14/05/14 21:51:05.96
例えば「足し算」ていうメソッドを作成したとする。
これは引数に例えば「1と2を入れると3が返る」というもの。

1「テストを書かないやりかた」

こんな簡単なメソッド、どうやってもミスるわけない。
とりあえず作る。最初に動くか確認する。
動いた・・・終わり

2「テストを書くやりかた」

「1と2を入力すると3が返る」というテストを書く。
開発しながらテストを走らせて正常か確認する。
テストが異常なら、異常がなくなるまでプログラムを修正する。
これをずっと繰り返す。

3「テストを先に書くやり方」

2のテストを先に書く。メソッドは空からスタート。
テストが通るまで開発を行う。

502:nobodyさん
14/05/14 21:56:32.40
console.logは、phpでいえばvar_dumpとかになるなんだろうが、
使うときにコメントイン/アウトしなきゃいけないし、消し忘れるとそれがそのまま出力されて大変なことになる(センシティブな情報だったら・・・)。

503:nobodyさん
14/05/14 22:52:25.27
上司がテストケース書いて、部下にそれに合うようなコードを書かせるってのなら良いと思う。

ただcakephp1が2になったりするとテストも書き直しだよね。
結局テスト書いてもそれ以上にプログラムの進歩が速いような気もするんだよね。

ちなみにヤフーとかって10年前くらいにcgiをphpに書き直したみたいなこと聞いたけど、あれ以来書き換えてないのかな。

それとも地道に書き換えまくってるのかな?

504:nobodyさん
14/05/14 23:08:58.07
>ただcakephp1が2になったりするとテストも書き直しだよね。

いきなりスパン長い話になってね?

ビジネスロジックまで全部変わるわけじゃないんだからテストコードも一部はそのまま使えるでしょ
テストコードまったくなしに書きなおすよりはいくらか書きやすいと思う

505:nobodyさん
14/05/14 23:36:50.08
>>499の説明で合ってるんだが、何がわからないのかわからない

506:nobodyさん
14/05/14 23:52:50.14
>>504
ありがとう。そういうメリットもあるんですね。

>>505
わからない人にとっては全くわからないんだよね。テストケースのメリット。


俺、gitもテストケースも使ったことないというか使えないので勉強します。

507:nobodyさん
14/05/15 00:48:57.49
なんだかんだ言って教えるのなw

508:nobodyさん
14/05/15 01:04:25.59
経験ないとわからないかもしれんね
愚者は経験に学ぶと言うけど人間なんて全員愚者だから、がんばって経験を積もう

509:nobodyさん
14/05/15 02:16:19.81
>>495
こういう >>492 時に必要になるんだよ。

例えば1日の区切りが0時じゃなく4時なサービスがあるとしよう。
DateTimeオブジェクトや日時の文字列を受けて、何日かを返すメソッドがあるんだけど、
中身を見たらこりゃひどい実装だなという時、
テストがあれば、中身を書き換えても同じ結果を返す実装にできたとわかりやすい。

510:nobodyさん
14/05/15 03:48:38.98
お前ら俺が以前テストの質問した時はスルーしたくせに
テストの話題で盛り上がりやがって

511:nobodyさん
14/05/15 04:08:36.66
>>510
たぶんそれから必死で勉強したんだよ

512:nobodyさん
14/05/15 10:33:38.61
>>509
>中身を見たらこりゃひどい実装だなという時、
>テストがあれば、中身を書き換えても同じ結果を返す実装にできたとわかりやすい。

ここが想像できないんだよ。中身(モデル?)が酷い実装っていうけど、
前は動いてたんだよな?それを変更する時に「酷い」が分かるんだろ?

なら、テストも書き直しだと思うんだよ。俺も>>503と同じ疑問を持ってる。
Cakeのバージョンアップではなくとも、仕様が変わればテストも変わるでしょ。

513:nobodyさん
14/05/15 10:45:22.44
0か1で考えてんな
少なくとも単体テストしやすいように設計してれば
仕様を変えた部分の他に影響がないことを保証しやすいんじゃないか


テストが書いてない誰かが作ったソフトウェアを改修する時に
あっち変えたらこっち動かなくなったよみたいな経験ない?

514:nobodyさん
14/05/15 10:52:06.00
んじゃあ次はgitってなんなのよ?

515:nobodyさん
14/05/15 11:08:32.04
>>514
俺も思うな。
一人で開発したことしかないからか、
前に戻したくなることなんてまず無い。

毎回、add、commitする手間の方が面倒な気がするけど。

ただ、いつでも何処にでも戻せる安心感ってのは大きいのかもしれない。
dropboxでも戻せるけどどこに戻せば良いのかすらわからない。

516:nobodyさん
14/05/15 11:14:00.56
>>512
別人だけど、中身ってコードのこと言ってるんだろ。
テストが完璧な仕様を表したものだと仮定すると、
テスト通りに動く限りは、実装コードはいくら変えても構わない、という理屈。
テストコードの方も変える必要がない(というか、変えたら同一の保証ができなくなる)。

もっとも、リファクタリングの過程で、新しいクラスやインターフェースを追加、とかなることが多いから、
その場合は、テストも変えていく必要はあるけど。

517:nobodyさん
14/05/15 11:25:10.47
バージョン管理してないとかマジか
まあ趣味で小規模のものならそれでもいいのかな…

518:nobodyさん
14/05/15 11:31:50.75
>>515
一人で開発を数年やってるが仕事でも個人サービスでもgitは重宝してる

過去ログとして何をやったかが残ること。
複数同時に機能開発ができること。
gitなしにはもう生きられない。

テストはControllerのテストは書かない。
それより下位層は書いてる。
自分が書いたコードを忘れたころに重宝してる。
他の機能実装のために、さらに下位層を変更したときに重宝してる。

デプロイツールもなしには生きられんな。

519:nobodyさん
14/05/15 11:48:03.50
>>517
残念ながら商用で10以上の製品を扱ってるんだ・・。

gitの前にSubversionを勉強したこともあったけど、
バージョン管理の利点があまり思いつかないんだよな。バックアップ以外で。

マイナーアップデートしてそれをgitで管理する程度ならいいだろうけど、
開発してたら頻繁に更新するわけだろ?コード間違えも多々ある。
なのに、どのタイミングでadd、commitするか分からんし、
毎回してたら515が言うように面倒だ。

520:nobodyさん
14/05/15 11:52:50.01
>>513
例えばこの2ちゃんの掲示板。
名前とメールアドレスと本文入れて投稿すれば掲載される。
この一連の処理が正しく行われるかのテストを書くわけだろ?

で、そこに「画像を追加できる」という機能が加わったとする。
コントローラーとモデルとビューにコードを追加し、テストも書き直すよな?
なら、またテストのやり直しだ。

521:nobodyさん
14/05/15 12:25:34.42
>>520
テストにもいろいろ種類があるが、ここで書け書け言われてるのは、
単体テストと呼ばれるやつな。

で、単体テストの場合、一連の処理をテストするんじゃなくて、
機能単位でテストする。
俺も理解は甘いから、機能単位と言い切って良いのかわからないけど。

なので >>509 のようなメソッドは、戻り値だけに着目すればよくて、テストが書きやすいんだけど、
コントローラーのテストはちょっと書きにくい。
コントローラーのメソッドはアクションで、実行されたあとの結果がいろいろあるからな。

522:nobodyさん
14/05/15 12:37:38.37
>>520
あえて掲示板ということで、CommentsControllerのaddメソッドのテストで考えてみると

1 必須項目を省いてPOSTしたら、書けてない事
2 書き込み成功していいPOSTなら、書けてる事
3 名前を省略したら「nobodyさん」になる事

もっとあるとは思うけど、addメソッドのテストとして、こんなのを確認するテストを書いたとする。

「画像を追加できる」機能が必須項目じゃなければ、「画像を追加できる」を実装した後も、
このテストは3つの部分は期待通りに動いてることを確認できると思う。
で、画像を追加する投稿についてのテストをいくつか追記して、機能追加が完成できる。
この場合あくまでテストは追記だから、テストは書き直しとは言わないと思う。

画像が必須項目だったとしたら、1と2は書き直しになっちゃうだろうけど、これも微修正って範疇じゃないかと。

523:nobodyさん
14/05/15 13:17:55.24
gitって、dropboxと違い
commitやマージが便利そうだな。

524:nobodyさん
14/05/15 13:33:34.19
>>522
物凄く分かりやすい!参考になった。
つまり、その1~3をこれまではブラウザでいちいち実行してたのを
テストコードさえ用意しておけば、自動で成否を出してくれるって事だよね?

それならテストを追加する意味もあるし、すごく便利だと思う。

525:nobodyさん
14/05/15 16:23:27.92
>>524
伝わったようで何よりだけど、あげておとすようで悪いが、
質問してた人が言ってたようなデメリットもやっぱりあるよ。

実装が大きく変われば、さすがにテストも修正というより書き直しになるし、
あとさっきも書いたけどコントローラーはテスト書きにくい。
仕様変更で実装が大きく変わりやすい箇所でもある。

あと >>522 この例でいうと、「画像を追加できる」機能を追加した際、
ぶっちゃけテストなんてなくても1~3は壊れないような実装になりそうな気がすごいする。

俺としては >>509 のような、ユーティリティ的なライブラリが、テストも書きやすいし恩恵も多いと思う。
実際困ったから書いたんだけど、時間というテストがめんどくさいデータで、
結局動作確認するには、4時丁度とその前後や、逆に0時丁度やその前後を引数に、呼んでみるしかないから、それってテストコードだしな。
で、ユーティリティだからサービスのいろんな箇所で呼ばれてて、ミスったときの影響範囲も広い。
なので、テストコードがないと、修正に及び腰になってしまう。

526:nobodyさん
14/05/15 16:45:41.71
>>525
なんかよく分からなくなってきたな・・・。
コード書いて「こういうイメージ?」って聞こうとしたんだけど、
どう聞けばいいからすら分からず、固まってしまったよw

527:nobodyさん
14/05/15 19:50:47.49
ここはなんのスレですか?

528:nobodyさん
14/05/15 19:53:03.77
スレタイ読めないの?CakePHPのスレですよ?
ちなみにCakePHPにテストという機能がちゃんと用意されてますよ?
だからその事について話し合っているんですよ?

529:nobodyさん
14/05/15 20:27:14.89
>>528
くわしく

530:nobodyさん
14/05/15 20:53:28.94
>>529
URLリンク(book.cakephp.org)

531:nobodyさん
14/05/15 23:34:57.49
>>525
テストコードがないと及び腰ってのすごくわかる。
自分が作ったコードですら触りたくないもん。

532:nobodyさん
14/05/16 13:54:12.18
では、先生方次は最近よく聞く
composerについて教えて下さい。

533:nobodyさん
14/05/16 14:02:22.96
あとで知ったかで話すから、ちょっと勉強する時間をくれ

534:nobodyさん
14/05/16 14:26:46.96
composerは依存する外部のライブラリ等を管理して
autoload処理までしてくれるもの

packgistに登録されているものの他に
gitやsvnとかで管理されているもの
zip等で落としてくるもの、PEARとかも管理できる

依存関係の解決や、バージョンアップの追従とかが簡単にできるのがいいね

更新時にスクリプト動かしたりもできるから、さらにいろいろ使えるよ

535:nobodyさん
14/05/16 14:41:38.71
cakeはcomposer対応がめちゃくちゃ遅かったよな。

536:nobodyさん
14/05/16 21:57:48.54
composerってRubyでいうとこのgem?

537:nobodyさん
14/05/16 22:04:02.91
bundlerかな

538:nobodyさん
14/05/16 22:12:07.93
>>537
なるほど、さんきゅー

539:nobodyさん
14/05/17 02:35:10.07
routes.phpで指定できるURLのパターンに、DBから取得した値を設定することってできる?
例えば、
/domain/DB値 みたいな感じで
ちなみに、1.3系

540:nobodyさん
14/05/17 03:35:24.78
>>539
2系では無理。routes.php のタイミングでは ClassRegistry がロードされていない。
1.3系は分からんが、やってみて確かめてみれば?

541:nobodyさん
14/05/17 03:39:32.10
Model使わずに直接SQL叩けば宜し

542:nobodyさん
14/05/17 05:32:08.69
>>539
うーん、たぶんできるんじゃね?

URLリンク(book.cakephp.org)
まず、カスタムルートクラスを使う。
Cookbookは英語しかないが、これ。

App::uses('CakeRoute', 'Routing/Route');
App::uses('ClassRegistry', 'Utility');
SlugRoute extends CakeRoute{
public function parse($url){
$parse = parent::parse($url);
$hoge = ClassRegistry::init('Hoge');
return $parse;
}
}

こういうカスタムルートクラス書いてみたら、$hogeにHogeのインスタンスがあることまでは確認した。
なお、phpがあるPCと、これ書いてるPHP別なので、上のコードにtypoがあるかもしれない。

カスタムルートクラスでApp::uses('ClassRegistry', 'Utility');することによる弊害があるかどうかは知らない。

543:nobodyさん
14/05/17 11:47:50.48
>>542
それは単にルータのクラスをRouteから変更するだけじゃん。

ルーティングのタイミング(routes.php の読み込み)は一緒だから
Model のインスタンス取得できないんじゃないかってことなんだけど。

544:nobodyさん
14/05/17 11:54:40.61
すまん、言葉足らずだった。
ルータのクラスを変更することは
ここでは問題になってないってことを言いたかっただけ。

で、今 routes.php で App::uses('ClassRegistry', 'Utility');
して Model のインスタンス取得したら問題なく動いたわ。
副作用は知らん。

1.3系は ClassRegistry ってないんだっけ?
途中から出来た?
その辺はよく分からん。

545:nobodyさん
14/05/17 12:16:13.55
WordPressが記事URLのルーティングを管理画面から変えられるけど、
あんな感じにできれば便利だなとは思う

546:nobodyさん
14/05/17 12:21:13.08
確かにそうだよな。
もっと初期段階でモデルにアクセスできる仕組みのほうがいい気がする。
他のFWとかのプロセスってこの辺りどうなってんのかな。
俺はCakeしか知らないから。

547:nobodyさん
14/05/17 12:58:47.14
>>546
全体のローダーとルーティングで制限がかかるローダーはタイミングが別なものが多いよ
前者でモデルの読み出しができれば使える感じ

548:nobodyさん
14/05/17 13:17:23.08
で、結局何が問題なの?

App::uses('ClassRegistry', 'Utility'); で初期段階でモデルにアクセスも出来たし、
あとはカスタムルートクラスで好きなようにパースして返せば、
良い書き方かはおいといて、動きそうな感じはしてるんだけど。

549:nobodyさん
14/05/17 13:46:47.18
うん、行ける気がする

で、>>548 こそ何が問題なの?

550:nobodyさん
14/05/18 01:51:53.74
>>549
質問に対してこれでできんじゃね?って方法を書いただけだから、
こっちに問題はないけど。

551:nobodyさん
14/05/18 02:42:01.29
この板、IDでないから誰が何喋ってんのか全く分からんw

552:nobodyさん
14/05/18 04:33:21.19
ところで、ClassRegistryが出てきたからついでに聞きたいんだけど、
new Hoge()じゃなくてClassRegistry::init('Hoge')が推奨されるのってなんで?

昔コントローラーじゃないところでモデル使うことがある時、
new Hoge()してるって言ったら、だめって言われたことあるんだけど、
まだ初心者だったら理由までは教えてもらえなかったんだよね。
よくわからないまま、ClassRegistry::init()を使うようにだけしてるんだけど、
理由知りたい。

553:nobodyさん
14/05/18 11:39:16.13
newしたら初期化されるじゃん

554:nobodyさん
14/05/18 12:23:32.63
phpunitのテスト駆動開発について。
テストを先に書くということですが、
メソッドを先に書く場合もありますか?

555:nobodyさん
14/05/18 12:34:06.68
また、掲示板サイトを作る場合、
記事を書く
記事を見る
記事を削除

の3つのケースを先に書いてテストし実装する
もしくは一つの機能ごとにテストを書く実装する、のどちらが良いのでしょうか。

556:nobodyさん
14/05/18 18:19:05.82
>>554
テストを先に書くことがテスト駆動開発の必須条件の一つだと思うんだけど、
別に原理原則にこたわることもないと思われ。
ただ、教科書的にはまずテストを書いて赤色から発進するのが通則。

>>555
テスト駆動開発は、一般的にはアジャイル開発の一部とされている
(たぶん、そうじゃない場合もあるはずなんだけどあまり記憶に無い)ので
単純なテストからだんだん複雑にして行くことを前提に、
最初は簡単な「記事を書く」テストを書いて実装して
簡単な「記事を見る」テストを書いて実装して、
簡単な「記事を削除」テストを書いて実装して・・・ってことなんじゃないかな?

だけどそれも程度によるだろうから、最初はざっくりアウトライン的に
全体を作って、作りこむに従って単体テストを増やしていったりテスト自体を
詳細にコーディングするってことでいいんじゃないかな?

557:nobodyさん
14/05/18 18:27:15.17
>>556
ありがとうございます!
勉強になります。

558:nobodyさん
14/05/18 23:31:40.02
まぁ自分で書いておいてこんなこと言うのもあれだけど、
TDDに限らず、ここで聞くより専門の書籍を一冊買って
それを読んで体系から身につけたほうがいい。

559:nobodyさん
14/05/19 16:50:44.06
画像のバリデーションで、画像をアップロードしていない場合は
バリデーション自体を中止したいのですが、良い方法はないでしょうか?
以下のようなルールをモデルに書いています。

'image' => array(
 array(
  'rule' => array('extension', array('jpg', 'jpeg', 'gif', 'png')),
  'message' => '拡張子が違います',
  'allowEmpty' => true,
 )
)

560:nobodyさん
14/05/20 15:39:04.32 RIYxfxGy
hasManyとfindについて質問です。

営業 1-多 顧客
というリレーションがあったとします。
営業 hasMany 顧客 と営業モデルに書いています。

そこで営業コントローラから 「顧客を一件ももっていない営業」をfindする方法がどうしても
思い浮かびません。 

どうかヒントをいただけませんでしょうか。

561:nobodyさん
14/05/20 15:56:13.36
営業 hasOne 顧客 というアソシエーションを一時的に張って、
検索条件を
'顧客.id' => null
とすれば行ける気がするのだがどうだろう。

あと、カウンターキャッシュという裏ワザもあるが、
アプリケーション依存になるんで一長一短。

562:nobodyさん
14/05/20 16:02:52.95
>>561
なるほど!試してみます。ありがとうございます。

563:nobodyさん
14/05/21 16:47:46.18
クックパッドってCake使ってるのかな?
なんかURLのルールが似てる気がする

564:nobodyさん
14/05/21 18:35:00.58
>>563
Railsじゃなかった?今は知らんけど

565:nobodyさん
14/05/21 19:54:17.38
ああ、Railsだから似てると感じるのか

566:nobodyさん
14/05/25 12:26:20.21
cakeとciのActiveRecordって
PofEAAのActiveRecordと違うと思うんだけど。何を元にしてるの?

567:nobodyさん
14/05/25 13:21:00.24
CakePHPにActiveRecordは実装されていない

568:nobodyさん
14/05/25 14:22:54.54
AppControllerを継承したクラスを継承したコントローラで
AppControllerに書かれた$uses、$componentsが使えない(マージされない)問題は
Cake2では直ってるんだっけ?
今確認できないのでどなたか教えてください

569:nobodyさん
14/05/25 16:32:17.75
>>568
Dispatcher でリフレクション呼び出してあれこれゴニョゴニョしてるんで、
多分大丈夫。
正式なアナウンスは知らん。

570:nobodyさん
14/05/26 20:03:50.85
>>568
その問題、今初めて知ったわ。

571:nobodyさん
14/05/26 21:17:51.86
久しぶりに自分が作った1.3のソース触ったけど、糞すぎて情けなくなる・・・

572:nobodyさん
14/05/26 21:34:55.75
オレの1.2のコードをやるから、その汚い糞を拭き取れ。

573:nobodyさん
14/05/28 12:20:55.53
カテゴリの状態を維持したまま別のコントローラーを実行するための
ルーティングってどう書けばいいですかね?

/hoge/ →Categoryモデルのname「hoge」
/hoge/news/ →Newsモデルのcategory_nameが「hoge」
/hoge/news/detail/1 →Newsモデルのidが1でcategory_nameが「hoge」

こういう場合、hogeの箇所(カテゴリ名)が不特定文字列なので
どういう書き方をすればいいか悩んでいます。cake2系です。

574:nobodyさん
14/05/28 12:29:00.97
Router::routes(array('/:category/'), array('controller' => 'categories'));

Router::routes(array('/:category/:controller/'));

Router::routes(array('/:category/:controller/detail/:id'));

でどう?

575:nobodyさん
14/05/28 12:33:07.08
あと、第三パラメータで正規表現でのフィルタリングができるんで、
3つ目のURLパターンにおいてIDは数値と決まっているなら

Router::routes(array('/:category/:controller/:id'), array(), array('id' => '[0-9]+'));

とすることで

/hoge/news/1

をマッチさせることが出来ると思う。

576:573
14/05/28 13:36:48.07
>>574-575
ありがとうございます。この方法ですが、
他のコントローラーと共存させたい場合はどうなるのでしょうか?

/contacts/ お問い合せ用のコントローラー
/faqs/ FAQ用のコントローラー

などがサイトに存在する場合、おかしくなるような気が・・。
そういう場合は、固定のコントローラーを
ルーティングに書いていけばいいんですかね?
Router::routes(array('/contacts/:action'), array('controller' => 'contacts'));

577:nobodyさん
14/05/28 13:55:25.16
問題ない。
ルーティングは単純な正規表現を先頭からマッチさせていくだけ。
で、最後の最後に通常のマッチングがコアの方に用意されている。

578:nobodyさん
14/05/28 13:56:01.83
あ、問題あるわ。すまんw

579:nobodyさん
14/05/28 13:56:49.69
>そういう場合は、固定のコントローラーを
>ルーティングに書いていけばいいんですかね?
>Router::routes(array('/contacts/:action'), array('controller' => 'contacts'));

そうですね。

580:573
14/05/28 15:29:39.46
>>579
ということは、固定のコントローラーは全てルーティングに書く必要があるんですね。
そうなるとあまり利便性が良くないですね。

581:nobodyさん
14/05/28 17:12:42.77
TreeBehaviorのleftとrightってなんなん…これ見ると存在しないid指定してるみたいでわけが分かんないよ…
URLリンク(book.cakephp.org)

582:nobodyさん
14/05/28 20:12:28.98
>>580
カテゴリ名を自由にするってことは、特定の文字を禁止にするんだろうから、
それを表現できるパターンを第3パラメータに書けば良いと思うよ。
たとえば ["member", "user"] というコントローラを作るんなら

$route = '/:controller/:action/*';
$default = array();
$options = array('controller' => '(member|user)');
Router::connect(compact('route', 'default', 'options'));

あと、アクションを設定しない場合に index を適用させるなら

$route = '/:controller';
$default = array('action' => 'index');
Router::connect(compact('route', 'default'));

を最初に加えておく。

あとすまん、
上で Router::routes() っていうのは Router::connect() の間違いだった。すまん。

583:nobodyさん
14/05/28 20:13:54.99
>>581
lft, rght はIDじゃないよ。

TreeBehavior のアルゴリズムを理解するのにとっておきの記事
URLリンク(blog.xao.jp)

584:573
14/05/28 20:20:05.04
>>582
ありがとうございます。色々工夫してやってみます。

585:nobodyさん
14/05/28 22:03:01.32
>>583
ありがとうマジで助かった!

586:nobodyさん
14/05/29 01:00:35.02
RailsとCakeでMVCを覚えたせいで見事に騙され、モデルはテーブルに紐付くもんと思ってたわ
テーブル関係ないビジネスロジックをどこに書くか迷って、コンポーネントに書いてたけど
モデルに書いた方がいいんだろうか?

587:nobodyさん
14/05/29 01:27:10.16
>>586
ビジネスロジックをモデルに書くのは常識だ。
コンポーネントに書いたほうが良いなんて聞いたこと無い。
Rails も Cake もその点においては何も騙してねーと思うよ?

588:nobodyさん
14/05/29 08:11:31.86
テーブルをまたがる共通処理や、似て非なるテーブルに同じ処理をしたい場合に、ロジックを置く場所がないて話だと思うけど。
そういう場合にRailsの1モデル-1テーブル形式は破綻してるのは確か。

589:nobodyさん
14/05/29 08:25:24.09
「具体的に言うと、モデルはデータベースのテーブルを表しますが」
URLリンク(book.cakephp.org)
とあるせいで、モデル=テーブルに紐付く(原則として)と思ってたよ
市販の解説書も同じような感じで書いてる

590:nobodyさん
14/05/29 08:44:24.60
>>587
モデルの中で他のモデルをClassRegistry::initとかやりたくないんだよ
コントローラに書きたくなければコンポーネントになる

591:nobodyさん
14/05/29 10:03:02.00 veg5U4SW
じゃあLibに作れよ

Modelじゃだめって理由でComponentに置く発想がおかしい

592:nobodyさん
14/05/29 10:04:39.91
は?LibよりComponentの方が使いやすいじゃん
Controllerの冒頭で配列に入れるだけで$thisで使えるんだから

593:nobodyさん
14/05/29 10:18:58.89
RailsにしてもCakeにしてもActive RecordないしTable Data Gatewayパターンを利用するクラスをModelと命名して
データベーステーブルと(さらにはコントローラとも)1対1対応しなきゃいけないように見えるから勘違いしやすいんだよな

Railsは1つのモデルに関するロジックは"モデル"クラスに書けるけど
Table Data GatewayのCakeはこれすらコントローラやヘルパーに溢れ出やすい印象

複数"モデル"が絡むときに簡易サービス層として利用されやすいのがコンポーネントなのかな
コントローラから呼びやすいしファットコントローラの一番楽な回避策だろうし


初心者でも(本来の広い意味での)モデルの中にサービス層を作りやすい実装や解説にしておいてくれるとありがたいんだけど

594:nobodyさん
14/05/29 10:27:52.09 veg5U4SW
>>592
なんだその理由ww

595:nobodyさん
14/05/29 11:21:59.06
>>594
何がおかしいんだ?

596:nobodyさん
14/05/29 11:35:25.87 Kdl2SKiZ
>>588

>似て非なるテーブルに同じ処理をしたい場合
これはビヘイビアがいい気がする。

597:nobodyさん
14/05/29 13:26:17.97
前もこの話題出たよな
結論は出なかった

598:nobodyさん
14/05/29 13:48:42.54
作るものの規模とかで最適な構成は変わるしね。
>>593 のいうサービス層が必要になる規模は、CakePHPではちょっと対象外なんじゃないかと思ってる。
CakePHPの中の人がどう思って作ってるかはしらんけど。

599:nobodyさん
14/05/29 15:11:21.10
複数モデルにまたがる処理をコンポーネントに書いている人は
$useTable = false の別のモデルを作った方がずっと楽だと思うんだが。

コントローラから直接参照できる点は一緒。
データのセット、バリデーション、フォーム値の復元。
使うモデルを $hasOne とか入れとけば ClassRegisry::init も呼ぶ必要ない。

600:nobodyさん
14/05/29 15:24:59.72
俺はコンポーネントでやる方が楽だけどな

601:nobodyさん
14/05/29 15:34:31.80
おれも >>599 と同じだな。
Modelの下にサブディレクトリ切ってAppでパス通すのもありだと思う。

Lib は他で作ったライブラリを置く場所にしてる。

コンポーネントはコントローラの処理を助けることが限定されている場合しか書く意味ない。
もちろん、そういうロジックだけならコンポーネントはすれば良い。

602:nobodyさん
14/05/29 16:13:20.58
複数ページにまつわる処理といえば、削除はどうしてる?
会員制サイトだと、以下のような構成がよくあるが、

会員
└日記
└お気に入り
└掲示板の作成や投稿

会員を削除すると、その下の投稿内容も削除しないとおかしい(と俺は思う)
だから俺は、管理画面で会員を削除したら、user_idがあるモデルは全て削除している。
削除はコントローラーに書いてる。

603:nobodyさん
14/05/29 16:24:33.64
>>602
会員モデルの削除を呼んだら消えるようにする

604:nobodyさん
14/05/29 16:37:36.60
>>603
hasManyでdependentをtrueだな。

俺も基本はそうしてるんだけど、>>602のに「画像」がある場合は困る。
各テーブルを参照して画像情報を取得し、削除していく必要がある。

605:nobodyさん
14/05/29 16:50:52.43
beforeDelete,afterDeleteでいいんじゃない

606:nobodyさん
14/05/29 18:18:39.64
そうすると、Userモデル内で他のモデルも呼ぶことになるぞ?

607:nobodyさん
14/05/29 18:23:19.16
>>606
画像に関して言ったんだけど

dependentで消せないものに関して、Userモデル内から他のモデル呼んでも問題ないと思うけどな

608:nobodyさん
14/05/29 20:03:02.45
deleteAll のコールバックって無いんだよね?

あれば Image モデルの afterDelete に
アセットを削除する処理を書いておけば良いのだろうけど。

saveMany や saveAll はコールバック効くのに
deleteAll は効かないってのもおかしな設計ではあるな。

609:nobodyさん
14/05/29 23:57:26.91
deleteAll はコールバックあるよ。
ないのは updateAll

610:nobodyさん
14/05/30 01:36:47.29
>>609
あ、そうなのか!
deleteAll の第3パラメータを true にするんだな。
今初めて気づいたわ。

じゃぁ、アセットの削除をそこに書けば良いわけか。

611:nobodyさん
14/05/30 10:22:00.45
つまり、どういう設計になるの?

612:nobodyさん
14/05/31 17:06:44.83
gitでcakephp管理する時、丸ごと全ファイルを管理するの?
それともビヘイビアとかプラグインとかだけ?
教えてください。お願いします!

613:nobodyさん
14/05/31 18:14:11.40
全部

614:nobodyさん
14/05/31 18:28:27.72
cakephpってまだcomposerに対応しきれてない?

cakephp2でcakephp/appみたいなの探してるんだけどないかな?

615:nobodyさん
14/05/31 18:39:11.86
>>614
composer 使ってるけど、対応しきれてないと思ったのはどの辺り?

616:nobodyさん
14/05/31 18:49:51.57
>>615
bakeでプロジェクト作らないといけないのに
ハードコーディングを直さなきゃいけないところとかかな

617:nobodyさん
14/05/31 19:51:01.39
それは composer というか bake project の仕様だなー。
include_path 通しておけばハードコーディングされなくなるけど。

618:nobodyさん
14/05/31 20:57:15.14
>>613
ありがとうございます!

619:nobodyさん
14/05/31 23:23:49.38
今日俺がセルフHABTM方式というのを発明したんだが
何のことだかわかる?正式な名前とかある?

620:nobodyさん
14/06/01 12:20:08.01
そういうプラグインがあった気がする

621:nobodyさん
14/06/02 00:43:40.92
>>619

class Entity extends Model {

 public $hasAndBelongsToMany = array(
  'RelatedEntity' => array(
   'className' => 'Entity',
   'foreignKey' => 'relational_id',
  ),
 );

}

こういうこと?

622:nobodyさん
14/06/05 11:57:49.53 +YUe8hGX
メール送信するコマンド作って実行したら
「コマンド ラインが長すぎます」
というエラーが出るのですが、何かわかる方いらっしゃいますか?

環境は以下の通りです。
Windows 7
CakePHP 2.3.10
PHP 5.3.5

ファイル:app/Console/Command/ApprovalShell

<?php
App::uses('CakeEmail', 'Network/Email');

class ApprovalShell extends AppShell {
public function main() {
$Email = new CakeEmail();
$Email->config('default');
$Email->from(array('hogehoge@aaaaaaa.jp' => 'ほげほげ'));
$Email->to('hogehoge@aaaaaaa.jp');
$Email->subject('お願い');
$Email->send();
}
}

623:nobodyさん
14/06/05 14:05:40.48
>>622
Windowsで開発するのやめれたらいいと思うよ。

よく知らんけど、Cakeのエラーメッセージは英語。
てことは、おそらくコマンドプロンプトか、代わりに使ってるターミナル系アプリの出してるエラー。
エラーメッセージから、cakeコマンドへのファイルパスや引数も含め、
実行しようとしたコマンドの文字数が多すぎた。
てことが予想出来る。

624:nobodyさん
14/06/05 16:25:42.75 +YUe8hGX
>>623
ありがとうございます。
おっしゃるとおりかもしれません。

625:nobodyさん
14/06/05 19:12:08.87
自分はローカル用のアプリをCakePHPで作ってコマンドライン多用してるけど
「コマンド ラインが長すぎます」
なんてエラーは出たこと無いな。

原文はなんて書いてんの?

626:nobodyさん
14/06/05 19:12:52.47
あ、もちろん Windows のクライアントね。

627:nobodyさん
14/06/05 20:29:33.26
みんなwindowsじゃないん?

628:nobodyさん
14/06/05 22:14:09.51
本番機はレンタルサーバでlinux系だけど社内にあるマシンは全部windowsなんで
普段はwindowsで開発、最終的なテストだけ本番機で行っているわ
PHPはわりと環境依存大きいけどcake使ってると依存度がかなり軽減されると思う

629:nobodyさん
14/06/05 22:23:36.19
俺はVM立てるな
その方がお手軽だし

630:nobodyさん
14/06/05 22:26:03.50
windowsで開発してるけど
phpとかmysqlはwindows上で動かすのは無駄だからやってない
vagrantで簡単に作れるしさ

631:nobodyさん
14/06/05 22:29:27.33 d26v3tZW
>>628
開発用のサクラ鯖に直結して開発してるぞ。
リモートプロジェクト

632:622
14/06/05 23:27:51.32 +YUe8hGX
解決しました。
おさわがせしました。
PHPのメール設定がおかしかったみたいです。

633:nobodyさん
14/06/06 00:56:33.55
そうやってなんでもWindowsのせいにすればいいニダ…

634:nobodyさん
14/06/06 01:07:28.95
XAMPP使ってるのは俺だけのようだな

635:nobodyさん
14/06/06 01:37:12.74
だって、Windowsで開発してなければ起こらないトラブルや、
しなくていい苦労って多いもの。

636:nobodyさん
14/06/06 02:32:32.38
windowsだと実行が困難なのってcronぐらいじゃね?
画面系で動作が変わるとしたらソース自体に問題がありそう

637:nobodyさん
14/06/06 03:44:03.22
システムコールとかメール送信とかOSの絶対パスみなきゃいけない時とか

638:nobodyさん
14/06/06 06:32:05.95
開発マシンで実行しないとbakeした時面倒なんだよ

639:nobodyさん
14/06/06 11:48:12.37
>>637 はわかるけど、>>638 は何で?

Windows と Mac 混在して bake してて問題ないんだが、
気づいてないだけかな

640:nobodyさん
14/06/06 12:18:51.00
知らないだけだろ

641:nobodyさん
14/06/06 13:35:54.13
>>640
今試しに同じデータベースを元にして Mac と Windows で bake したのを
git で比較したけど差分なかったぞ?

642:nobodyさん
14/06/06 13:45:08.57
>>641
バージョンは?

CAKE_CORE_INCLUDE_PATHって何定義してる?

643:nobodyさん
14/06/06 15:39:44.51
>>642
2.5.1
CAKE_CORE_INCLUDE_PATH はコアの Cake ディレクトリを格納している
ディレクトリのパス。

644:nobodyさん
14/06/06 15:59:39.81
>>643
CAKE_CORE_INCLUDE_PATHに差があるんじゃない?

645:nobodyさん
14/06/06 17:22:45.98
>>644
そりゃ絶対パスだから違うわけだけど、
bake して生成された結果には影響ないよ?

ちなみに今の論点はあくまでも
>bakeした時面倒なんだよ
に対する疑問ね。

646:nobodyさん
14/06/07 13:17:32.00
composerについて
これは、phpファイルのみしか管理できないのですか?
例えばjqueryとか、画像も管理できるのでしょうか?

教えてください。
よろしくお願いします。

647:nobodyさん
14/06/07 14:18:28.71
>>646
composerは基本、外部のライブラリを管理したり
プロジェクトの作成に利用したりするもの

jqueryは
component/jquery
を使えば管理できる

画像は外部のものなのかい?

648:nobodyさん
14/06/07 14:22:04.06
>>647
ありがとうございます。
画像やjqueryはプラグインに入れようと思って、それをbitbucketで管理します。

全てのサイトでそのプラグインをcomposerで管理できるのかなとおもいまして。

649:nobodyさん
14/06/07 14:26:11.05
>>648
bitbucketで
各々サイトと、jqueryのプラグインを別に管理したとして

>全てのサイトでそのプラグインをcomposerで管理できる
ってのは可能だよ

650:nobodyさん
14/06/07 16:46:31.63
>>649
ありがとうございます!
早速やってみます。

651:nobodyさん
14/06/10 09:20:20.15
URLリンク(cakephp.jp)
これと同じ問題でハマってます
どうすればいい?
users/123 等の時は users/index/123にしたくて
users/read
users/edit
などアクション名を指定した時は、そのアクション実行したいのですが

652:nobodyさん
14/06/10 10:48:00.76
>>651
正規表現で絞れば良いだけじゃないの?

Cakeは最近使ってないからわからんが

653:nobodyさん
14/06/10 11:13:53.54
おお、性器表現も使えるのか
どこかにサンプルはないでしょうか?

654:nobodyさん
14/06/10 13:57:21.11
>>653
URLリンク(api.cakephp.org)
URLリンク(book.cakephp.org)

655:nobodyさん
14/06/10 17:33:53.47
>>654

結局正規表現使わなかったけど、解決しました

656:nobodyさん
14/06/11 00:44:51.34
twitterのように自分自身のユーザ情報のみ
編集可能にする方法を教えて下さい。
(他人のユーザ情報は編集不可、表示のみ)

657:nobodyさん
14/06/11 00:46:47.80
ログインユーザと編集する対象のユーザが同じかどうか確かめればいいだけじゃん

658:nobodyさん
14/06/11 00:51:45.60
>>657
ありがとうございます。
一致したら「編集」ボタンを表示する、などの処理をすれば良いのでしょうか?

659:nobodyさん
14/06/11 01:06:59.37
基本的に信頼していいのは自分がプログラムにハードコーディングしたサーバ側の処理だけ
クライアント側は他にアプリを作ればどんなHTTPリクエストでも送れるからだ

編集ボタンを表示しないのも予防策にはなるが
根本的にはサーバ側でデータベースのアップデートやセーブやデリートをする前に
CRUDの対象となるレコードがログインユーザ自身のものかどうかを確認するステップが必要
より具体的にはログインユーザのIDと更新するユーザテーブルのレコードのIDが一致するかどうかだ

660:nobodyさん
14/06/11 02:19:09.44
>>658 は、ちゃんと >>659 の言ってることを理解できたのだろうか・・・

661:nobodyさん
14/06/11 08:53:19.95
リクエストにユーザーIDをつけない

662:nobodyさん
14/06/11 10:34:05.54
あれ?
ユーザー情報の更新のリクエストにユーザーIDを含むようなフォームを作ったとしても
Cakeのパラメータ改ざんとCSRFのチェックが有効なら
悪意あるユーザーがフォームを改ざんして他のユーザーIDに変えたら
パラメータ改ざんチェックで引っかからんのかい?
教えてエロい人


まあそれでも>>661みたいに根本的に他のユーザの情報を更新できないようにしたほうが安心安全か
人為的なミスも起きにくいし

データベースを変更しないユーザー情報表示画面の時だけリクエストにユーザーIDを含める
ユーザー更新・削除時は対象レコードの選択にログインユーザのIDをそのまま使う

663:nobodyさん
14/06/11 17:28:51.09
>>662
CSRF対策は、そのページに行くまで正しい経路をたどってるかどうか
フォーム改ざんは、そのページに含まれるポスト対象のフィールドが正しいかどうか

のチェックだったはず。なので、POSTされるフィールド値を変更されたとしても、
Cake側では対応できないはず。

664:nobodyさん
14/06/11 20:19:39.05
ありがとうございます。
皆様のおかげでテストケースの有用性がわかるようになりました。
composerの便利さも。

jenkinsとかはどうなんですか?

665:nobodyさん
14/06/11 21:00:28.09
>>568の問題、2.5でも直ってねーじゃねーか

AppControllerを継承したAdminControllerを継承したEventControllerを動かしたら
AdminControllerのusesに書いてあるモデルが、AdminControllerのbeforeFilter内で使えなかったぞ
EventControllerのusesに追加したら動いたが、なんだかなー

666:nobodyさん
14/06/11 21:09:11.43
>>665
マージする継承クラスを指定できるパラメータがあったはず。
ドキュメント読んでみて。

667:nobodyさん
14/06/11 21:52:04.25
>>666
$_mergeParentのことか?
これでAdminControllerを指定したら、今度はAppControllerをマージしてくれないからダメ。
ぐぐったらこれ皆困ってるらしくてそれぞれ独自に_mergeVarsを改造したりして直してるな。
なんでこの問題公式が放置してるんだ?

668:nobodyさん
14/06/11 22:06:20.17
>>667
あ、本当だな。
CakePHPが糞と言われるのがよく分かるwww

669:nobodyさん
14/06/11 22:07:34.04
それがCakeクオリティ!
3の開発で忙しいんじゃないかな(*´∀`*)

670:nobodyさん
14/06/11 22:43:50.86
糞とか言ってる暇があったら issue 出すか、プルリクしろよ。



オレはやんないけど。

671:nobodyさん
14/06/12 01:35:46.71
>>670 出したところで却下かと。

>>667 はいくつかのコントローラに共通する機能が必要なら、
その時は継承ではなくてコンポーネントを作ったらどうかな?
コンポーネントはそのために存在しているわけだし。

共通機能を継承で得ようとするのは、言語やフレームワークを問わず、
あんまり良い選択ではないと思うけど。

672:nobodyさん
14/06/12 01:39:01.21
え?
うーむこれがPHP脳というやつか

673:nobodyさん
14/06/12 01:48:11.52
>>672
言語は問わないと書いたがな。
たとえば

EffectiveJava 第4章 項目14「継承よりコンポジションを選ぶ」

コンポーネントは文字通りこのコンポジションパターンだよ。

674:nobodyさん
14/06/12 02:42:37.90
>>671
>>665の例で言うと、EventController(他にもあるが)は管理者専用機能のコントローラである。
管理者用コントローラに共通の処理(ログインなど)をAdminControllerに書き、EventControllerはそれを継承した。
同じことをコンポーネントでやろうとすると、すべての管理者用コントローラーに
まったく同じコード(コンポーネントのメソッドを呼び出すコード)を書かねばならないのでは?
非常に不便だと思うが、俺が勘違いしてたら教えて欲しい。

675:nobodyさん
14/06/12 02:56:04.36
Controller::beforeFilter() に言及してたから、
その処理なら Component::startup() でいいんじゃないかと思ったんだけど、どうだろう?

場合によってはメソッドの呼び出しも必要になるけれども
けど、それは parent:: で親クラスのメソッドを呼ぶのとそれほど変わりないのかなと。

676:nobodyさん
14/06/12 02:57:29.99
>>671 がややずれてるのは
>いくつかのコントローラに共通する機能

としてるけど、>>665 で問題にしてるのは
広い意味では機能で間違いないんだけど
単に設定値である点においてズレてる。

ここではそれこそ、コンポーネントの
使い方なんかを指定しているわけで、
これは継承してほしいと思うよ。

677:nobodyさん
14/06/12 03:11:49.49
>>676
1.x系からのふるまいだから、仕様変更が入る可能性は低くないかな。

どうしても継承の継承が必要なケースで
さらに、孫クラスに基底クラスから継承させたいパラメータがあるなら
基底クラスのコンストラクタで $this->uses に入れればいいわけだし。

678:nobodyさん
14/06/12 09:12:51.74
こんなゴミなもの対応されたら
また名が廃る

679:nobodyさん
14/06/12 11:19:04.70
3のソースからは $_mergeParent は消えてるみたいだな。

680:nobodyさん
14/06/12 11:22:15.38
常識的に考えて、マージしないとおかしいだろ
何だこの仕様

681:nobodyさん
14/06/12 11:22:23.38
3使ってる人いるん?
どんな感じですか?

682:nobodyさん
14/06/12 11:28:47.32
3は継承全部マージされるよ

パフォーマンスはお察し

683:nobodyさん
14/06/12 12:11:49.21
3に苦労して移行するくらいなら、LaravelとかRailsに移るかな。
使ってこそのフレームワークだから、コミュニティの勢いは重要。

684:nobodyさん
14/06/12 12:25:24.65
cakeとsymfonyが本命FWとして争っていた時期が懐かしい

685:nobodyさん
14/06/12 13:23:35.06
みんな良く勉強できるな。他の言語に移るのは辛いわ。。。

686:nobodyさん
14/06/13 08:29:35.00
Cake使い続けるほうが長期的に見て辛い

687:nobodyさん
14/06/13 08:39:23.01
それはあるw
書いたコードの分だけ、負債がどんどん増えていく

688:nobodyさん
14/06/13 09:00:43.34
その負債の原因がCakeではなく自分にあるとも気づかぬままにw

689:nobodyさん
14/06/13 10:44:08.86
管理者用の機能って、Adminコントローラを作るんじゃなくて
adminプレフィクスを使うのが一般的な方法だと思っていたんだが
実際のところみんなはどうやっているんだ?

690:nobodyさん
14/06/13 11:00:42.12
>>689
俺はクッキーでログイン画面作って、セッション有る無しでview表示を少し変えてる。
ずっとこれでやってるけど。。。
ダメかな?

691:nobodyさん
14/06/13 12:20:32.10
一般利用者も管理者も同じaction通してるってことか。
全体的に管理者の機能が一般利用者とそんなに変わらなければそれでもいいのかもね。
プレフィクスを切っている場合でも

public function admin_search() {
$this->search();
}

なんてコードは実際に書かれるわけで。

692:nobodyさん
14/06/13 14:29:24.42
>>689
面白そうだったんで最初やってみたけど、
同じクラスにヤバいアクションが混在するのが気持ち悪い。
それ以降やったこと無いな。

>>690
表示だけならそれでいいんじゃない?

693:nobodyさん
14/06/13 17:20:45.32
俺は管理画面と一般画面のappは分けてるよ
管理画面だけ変えたい設定(キャッシュしないとかdebug2とか)があるし。

694:nobodyさん
14/06/14 17:11:30.81
みなさん、ホーム画面ってどのコントローラーでやってます?
ホーム用のコントローラーを作るか既存のコントローラーでやるか

695:nobodyさん
14/06/14 17:15:43.40
ホーム専用

696:nobodyさん
14/06/14 17:19:19.02
専用じゃないや
HomesControllerだけど他にもaboutとかシンプルなページと兼用

697:nobodyさん
14/06/14 17:26:13.81
>>696
その場合、コントローラー付きで直アクセスされた場合、
何かリダイレクト処理を入れてるんですか?
(/homes/indexとか/homes/aboutでアクセスされた場合)

698:nobodyさん
14/06/14 17:37:45.91
>>697
routes.php弄る

699:nobodyさん
14/06/14 17:42:44.81
あ、違うな
対策はしてない
最近やってないから忘れてる…

700:nobodyさん
14/06/14 18:59:09.94 dq/AB5k+
ルーティングについて質問です。
URLに「hoge」がついていたら、パラメーターをhogeとして受け取りたいです。

/users/        →UsersControllerのindexアクション
/users/detail     →UsersControllerのdetailアクション
/hoge/users/     →UsersControllerのindexアクションでパラメーターhoge
/hoge/users/detail →UsersControllerのdetailアクションでパラメーターhoge

というイメージなのですが、こういう事はルーティングの設定で可能でしょうか?
可能なら書き方を教えてください。2.4系を使用しています。

701:nobodyさん
14/06/14 21:50:21.39
>>700
できるよ


/* /hoge/users/ がマッチする設定 */
$route = '/hoge/users/';
$defaults = array('controller' => 'users', 'action' => 'index', 'hoge');
Router::connect($route, $defaults);

/* /hoge/users/ がマッチする設定 */
$route = '/hoge/users/:action';
$defaults = array('controller' => 'users', 'hoge');
Router::connect($route, $defaults);

/* /users/ と /users/detail は設定なしの標準でマッチ */

702:nobodyさん
14/06/14 21:54:32.07
あ、コメントミスった。正しくはこっち


/* (1) /hoge/users/ がマッチする設定 */
$route = '/hoge/users/';
$defaults = array('controller' => 'users', 'action' => 'index', 'hoge');
Router::connect($route, $defaults);

/* (2) /hoge/users/detail などがマッチする設定 */
$route = '/hoge/users/:action';
$defaults = array('controller' => 'users', 'hoge');
Router::connect($route, $defaults);


/users/ と /users/detail は設定なしの標準でマッチ
(2) のパターンは detail 以外のアクションにも適用されることに注意して。
もしアクションを限定したいのなら別の書き方が必要。

703:700
14/06/15 00:45:45.76
>>701-702
ありがとうございます。大変参考になりました。

704:nobodyさん
14/06/15 14:07:12.52
フォームヘルパーのinput作成のname部分を
data[Model][name]→nameにする方法って無いでしょうか?

705:nobodyさん
14/06/15 16:51:00.51
>>704

FormHelper のパラメータでってことなら不可。

706:nobodyさん
14/06/15 17:42:36.89
>>705
やっぱり無理ですか。諦めます

707:336
14/06/15 18:33:33.91
>>706
オーバーライドして、アウトプットを置換するだけじゃん

708:nobodyさん
14/06/16 00:20:49.49
フォームヘルパー本当に使い辛い
散々ハマった挙げ句、自分でFormタグ書いてるわ

709:nobodyさん
14/06/16 12:40:04.49 2sVNmbqM
現在、cakeのAuth認証を使ってログインシステムを作っているのですが
一度登録済のパスワードをユーザ操作により変更した場合、
パスワードの認証対象の値はハッシュ値で自動でDBに登録されるのですが
それを再び登録し直すにはどうすれば良いのでしょうか?


例)
[入力パスワード]  [ハッシュ値]
testpass  ijierwaaasdfkjiewi32jasdfkj3

↓ ユーザがパスワードを変更した場合
testpass2 asdafasdfasjd・・・etc ←ハッシュ化する関数は何でしょうか?

710:nobodyさん
14/06/16 18:38:51.83
フィームヘルパーのselectで0の値が空欄になるのは仕様ですか?

711:nobodyさん
14/06/17 00:26:53.74
>>709
Security::hash($password, null, null)

ちなみに v2.4 までは
AuthComponent::password($password)
だったけど、2.5 からは非推奨。

712:nobodyさん
14/06/17 00:34:56.25
Security::hash() の第2と第3パラメータは要らないみたいだ

Security::hash($password)
でOK

713:nobodyさん
14/06/17 06:18:50.52
CakePHPてprimary idは必ずauto incrementのintでないと駄目なん?
INSERT時にidがnullであることを前提にしてるから、自前でid渡すと
バリデーション時にisUniqueやonCreateの指定がうまくいかなくなるね。
これはCakeではそういうもんなのか。自前でバリデーション書くしかないのか。

714:nobodyさん
14/06/17 11:33:53.22
>>713
Model::$primaryKey で設定
動的な変更も可
複数キーは不可。3から対応

715:nobodyさん
14/06/17 11:38:54.51
>>713

>バリデーション時にisUniqueやonCreateの指定がうまくいかなくなるね。

そうか?

716:nobodyさん
14/06/17 12:03:04.11
>>714
それはもちろん指定してる。
だが、isUniqueやonCreateはうまくいかなかった。
結局数字のidを追加して対応した。

717:nobodyさん
14/06/17 12:32:01.97
あぁ、そういうことか。なるほど。
onCreate は使ったこと無いんでよく分からんけど、
isUnique は、保存前に Model::$id をセットしてやってもダメなん?

718:nobodyさん
14/06/17 16:22:43.39
>>717
それは試してないな。primaryKeyの名前がidじゃなかったから、idは一切いじらなかった。
Model::isUniqueのソースあらためて見たら、$this->idにNULLを入れていたらうまくいったかもしれん。

719:nobodyさん
14/06/17 17:08:04.87
Model::$id は、primaryKey の値のことなので、
スキーマのフィールド名が id であるかどうかとは無関係。

720:nobodyさん
14/06/18 03:28:03.88
>>719
なるほど!
後で試してみよう

721:nobodyさん
14/06/18 12:55:32.95 1XJ5G0pn
すみません、今ドットインストールの講座が終わりまして、
自分でCakePHPのサイトを作ろうと思っているのですが、気になった点がありました。

今、作ろうとしているサイトは、ポートフォリオ系になるので、
自分が作ったゲームやWebサイトを置く予定であります。
CakePHPを使う必要性は薄いのですが、フレームワーク経験が必須なため、
経験を積むという意味で、CakePHPを使用しました。
そして、サイトには、大きく分類して、トップページ、ゲーム、Webサイト、リンクがあり、
それぞれ、topsテーブル、gamesテーブル、sitesテーブル、linksテーブルがあります。

そこで、気になったのが、
CakePHPでは、Controller、View、Model、データテーブルの名前を揃えなければならないと習ったのですが、
そうなると、出力するテーブルが違う場合は、GamesController、SiteControllerのように、
コントローラーとフォルダを用意すべきでしょうか。
それとも、1つのコントローラー、1つのViewフォルダにまとめられるでしょうか?

722:nobodyさん
14/06/18 13:01:47.43
好きなようにすれば良い

723:nobodyさん
14/06/18 13:23:44.25 1XJ5G0pn
つまり、Controller名、フォルダ名と異なるテーブルを使用することは可能で、
特に問題ないとのことでしょうか?

724:nobodyさん
14/06/18 14:07:44.93
>>721
topsってテーブルが気になるな。何があるテーブルか分からん。
sitesテーブルとlinksテーブルの違いとか。

お前さんの用途は「自作のゲームやWebサイトの情報を公開する」だろ?
じゃ、「products」テーブルだけか、分けても「links」「games」だけだと思うんだが。

あと、基本的なCakeの命名規則が分かってないよ。

Controller:GamesController
Model  :GameModel
View   :Games
テーブル:games

725:nobodyさん
14/06/18 14:20:51.04 lT0uB39l
>>711 >>712

ありがとうございます!!

726:nobodyさん
14/06/18 14:29:45.54 1XJ5G0pn
説明がたりませんでした、申し訳ありません。
Webサイトに載せるのは、ゲームとWebサイトです。

topsは、トップページなのですが、ここに更新履歴を置くところです
sitesは、メインとなるホームページ以外に作った、Webサイトを置くところです。
ここでは、ゲーム以外の製作物と認識してくだされば十分です。
linksは、素材とかをお借りしたサイトとかへのリンクです。
gamesテーブルとsitesテーブルは、productsテーブルにまとめたほうがよさそうです。
ご助言ありがとうございます。

そうなると、
Controller:TopsController
Model  :TopModel
View   :Tops
テーブル:tops

Controller:GamesController
Model  :GameModel
View   :Games
テーブル:games

Controller:LinksController
Model  :LinkModel
View   :Links
テーブル:link

という風に分けた方が、使用するテーブル単位で分けた方が無難ということでしょうか

727:nobodyさん
14/06/18 15:13:40.83
だからtopsって何なんだよw
更新履歴ならnewsとかupdatesとかにしたらどうだ?

728:nobodyさん
14/06/18 15:41:33.35
1XJ5G0pnはもう少し勉強したほうがいいな。根本的なMVCが分かってない

729:nobodyさん
14/06/18 15:45:20.63
いや英語を勉強した方がいい

730:nobodyさん
14/06/18 16:30:07.27 1XJ5G0pn
すみません、画面名からテーブル名作ってしまいました。
最初は、更新履歴を表したテーブル名は、newsでつけていたのですが、
コントローラー名とフォルダ名を揃えなければならないということ思い出して、
それでトップ画面の名前を、更新履歴のテーブル名にしてしまいました。
(トップ画面に更新履歴を表示させるため)

それで、テーブル名とコントローラー名、フォルダ名がずれていても問題ないということでしょうか?

731:nobodyさん
14/06/18 16:39:06.81
モデルとコントローラはむしろずれてないとバグりやすくなるだろ。
1画面にニュースとリンクを両方表示したいときどうするつもりだ?

画面に名前をつけたのがView、データの集まりに名前をつけたのがModel。
Cakeでは便宜上Viewのフォルダ名とコントローラ名を合わせると幸せになれるというだけ。

732:nobodyさん
14/06/18 16:39:37.90
ずれるの意味が分からんが、MVCでバラバラなら問題あるだろ

733:nobodyさん
14/06/18 16:59:54.99 ma+gijMn
秒速で1億稼ぐ豚が・・・レイプ

URLリンク(www.tanteifile.com)

734:nobodyさん
14/06/18 17:34:03.35
上の方でも誰か書いてるけど、1XJ5G0pn はまず好きにすればいい。

つまり、いろいろ質問してるけど、とにかくやってみてから
問題を見つけて行ったほうがいい。

手を動かさない奴に何をいっても無駄だ。

>という風に分けた方が、使用するテーブル単位で分けた方が無難ということでしょうか

などという小賢しい質問をする前にまず作れ。
そして壊して作りなおせ。

735:nobodyさん
14/06/18 23:32:42.92
Cakeマスターの皆さんに質問

ViewからModelのvalidateを参照して、「名前は○文字までです」みたいな表示をしたい。
ベストプラクティスなやり方ありますかね?

もしくはViewからもModelからも見える所に数値のdefineを置くべきだろうか。

736:nobodyさん
14/06/19 00:35:54.86
>>735
文字数制限をViewでも管理したいってことか?
そう頻繁に変わるものじゃないから、
Viewに直接注意書きを書くのが一番だと思うが

737:nobodyさん
14/06/19 01:10:02.52
うちは最近設定値関係は Config に json で保存するパターンを試してる。
パーサのオーバーヘッドが多少気になるけど、まぁ悪くない。

738:nobodyさん
14/06/19 01:18:19.13
>>736
Viewから変更する必要はなく、注意書きを書きたいだけなんだよね
制限文字数なんかは後から変更される可能性があるので、ModelとViewの両方に直書きしたくない
やはり設定ファイル式にすべきか

739:nobodyさん
14/06/19 02:04:30.51
Configモデルに数値を保存してコントローラーから操作すればいいじゃん。
モデルキャッシュを使うと、重くならないぞ

740:nobodyさん
14/06/19 02:06:51.32
viewからmodelを参照するのは全く構わないと思う。俺はviewからいつでもmodelのインスタンスを参照できるように$getmodel('Foo')みたいなクロージャを用意してるので、バリデーションルールにもアクセスできる。

741:nobodyさん
14/06/19 16:22:55.58
Cakephp2で、core.phpのprefixesを有効にしています。
Configure::write('Routing.prefixes', array('admin'));

routes.phpでルーティングをしたい時、
Router::connect('/', array('controller' => 'pages', 'action' => 'index', 'home'));
Router::connect('/admin/', array('controller' => 'pages', 'admin' => true));

としているのですが、同じような内容を2回書くのが面倒です。
これは仕様として仕方ないのでしょうか?

742:nobodyさん
14/06/19 23:44:09.30
cakephpを2から3に上げる時とか、
業務でやってたら怖くない?
慣れなん?

サーバー移転ですら怖くてできん。。

743:nobodyさん
14/06/19 23:45:58.63
業務システムのフレームワークをベータ版にしようとするお前がこえーよw

744:nobodyさん
14/06/19 23:47:32.48
>>743
今はそうだけどさ
仮にstableになっても。

745:nobodyさん
14/06/20 00:11:16.79
2->3 はハードル高そうだな

746:nobodyさん
14/06/20 01:16:57.68
2であと3年は戦うつもり

747:nobodyさん
14/06/20 09:35:32.81
3に変えてまでCakeについていく気はないな
別のフレームワークに変えるだろう
でも今からだと何がいいんだろう

748:nobodyさん
14/06/20 10:09:05.76
>>747
ファルコンってどうなん?
速いみたいだけど。

749:nobodyさん
14/06/20 11:20:56.99
>>747
laravelじゃないか

phalconは業務でも使ってるけど
バグはそれなりにあって、Segmentation Faultで落ちると結構大変
速度は比較にならないほど速いし、フレームワークの仕組みも良いけどさ

750:nobodyさん
14/06/20 16:37:24.67 1CC0efjo
cakePHPを使ったシステムで
アップローダーを作ろうとしているのですがウィルスファイルをアップロードされると不味いので
アップロード可能なファイル種類を事前に jpg のみに制限しておいた方が無難でしょうか?

751:nobodyさん
14/06/20 17:18:38.33
>>750
どうやって制限するの?

752:nobodyさん
14/06/20 17:31:29.21
>>751
バリデーションに書く

753:nobodyさん
14/06/20 17:41:37.43
>>752
mimetypeで制限するってことか

jpeg画像のウィルスとかもあるからねぇ

754:nobodyさん
14/06/20 17:53:47.33
つーか、jpeg型ウィルスって実行するには
別のウィルスに感染させる必要があるんだろ?
単に画像を閲覧しただけで感染するなら、対策とか無理じゃないか?
twitterとかfacebookはウィルスだらけになるぞ

755:nobodyさん
14/06/20 18:27:17.32 I3iP4JeK
という事はつまり、jpgファイルであったとしても >>754のアドバイスを参考にすると

jpgのみアップロード可能にしておけば、ウィルスに感染していない人が

その画像を閲覧する分には何も影響がないと言う事でしょうか?

ウィルス感染している人自体が少ないと思うので被害は少ないですよね。

756:nobodyさん
14/06/20 18:38:27.21
>>755
と言うより、防ぎようがない気もする。
でも、画像アップロード出来るWebサービスは日々オープンしてるわけだし、
そこまで神経質になっても仕方ないよ。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch