肉とビールとパンケーキ by @sotarok

少し大人になった「肉とご飯と甘いもの」

ActionFormの基本的な考え方

まず、色々勘違いしていた自分の頭の中をここでさらけ出し、それに対する答えを次に書くという形にしようと思います(笑)

  1. ActionFormの$formに設定するのは、「<form>」からの値だけだと思っていて、それ以外のパラメータ(ページ送りようのパラメータとか)はどうやって受け取るの?$_GETをそのまま使うの?って思ってた
  2. 1つのプロジェクトの中で多用するForm値は ProjectID_ActionForm を継承した ProjectID_ActionForm_Form1 のようなものをつくり、それを継承させたActionFormをつくっていた


とりあえずどうしてそういう考えにいたったか。

1.については、まず、「ActionForm」という名前に惑わされました。ここに設定するパラメータは、「フォーム値」のためにあるものだと思い込んでしまい、登録フォームからの値、ログインフォームからの値、新規投稿フォームからの値などのみを設定するものだと思ってました。てかよく考えたらどこにもそんなことかいてないんですけどね。そんなわけで、「じゃあページ送り用のパラメータ $p とか、記事詳細を見るための $article_id だとかって、どうやってとればいいの?」という疑問にぶちあたってしまったわけです。頭が固くてすいません。
で、実際にはそんなことはなくて、$p だとか $article_id だとか、そんなものを全部 ActionForm に定義してやればいいわけですよね。もちろんデフォルトでそのパラメータがつかないならば、

 'required' => false,

なんてしてやればいいんですし。
これってすげー便利。だって今まで受け取るパラメータすべてリストして、漏れがないようにバリデーションしなきゃ、って考えていたものが、

  • そもそも ActionForm に定義しなければ値を取れない
  • ActionForm では型や受け取る値への制限(regexp や custom で)がかけられる

という2点の機能(制約)があるから、そんなこと考える必要なくなるわけですよね。$p は整数!って自分で調べなくてよくなるわけだ。*1

いやあ、つくづくよくできてるなーと思った瞬間でした。


2.についてです。
そもそも、どういう場面でそんな話が出てきたかというと、掲示板スクリプトを作っているとき、「新規投稿」「返信」「編集」どのアクションにも、同じ項目を使うよね、と思っていました。「名前」「タイトル」「内容」です(まぁもっと言えばもっと色々あるわけですが)。で、これらのすべてのアクションの ActionForm には同じ項目をセットしなければいけなくて、「じゃあひとつ書いて全部にコピペ?」とも思ったのですが、それだとせっかくの「同じコードを書かないEthnaの意味がないのでは」と考え、「じゃあ継承させるクラスもひとつ作ればいいじゃない」と考えたわけです。
まぁ大はずれな考えではない(と思いたい)けど、そこはEthnaさん、ちゃんと考えられてますよね、そうですよね(笑)
おおもとの ProjectID_ActionForm の中に、$form_template なんてものがいて、そいつに定義を書いてしまえば、ActionForm の中で

<?
 $form = array(
     'foo'    => array(),
     'bar'    => array(),
      ...
 );

みたいにするだけで、$form_template に記述した定義を呼び出すことができるらしい。これってめちゃくちゃ便利なうえに、プロジェクト全体で統一感を持ったフォーム値定義ができるというおまけつきなんですね。例えば、同じページ送り用の $p にしても、Aというページに対するページ送りと、Bというページに対するページ送り、といったように複数定義してしまうと(本来は関連性がないわけですからね)、それぞれに対してそのときの気分でフォーム値の定義が生まれてしまいますよね。*2そういうのが、防げるという。
で、プロジェクトの中で使うフォーム値は片っ端からここに定義してあげれば、あとは呼び出すだけ、というカンジなんですね。素敵です。


まぁよく考えてみると、当たり前のことですが、個々一番さんに聞くまで自分で気づけませんでした。情けない。。(「フォーム値以外のGET値ってどうやって受け取るんですか?」と質問したときめっちゃキョトンとされてしまったし^^;)
どうせだったら、ActionParam とかいう名前ならよかったのに・・・といってみたり(笑)


というわけでまとめると、

  1. すべてのパラメータはActionFormに定義する。フォームだろうがただのパラメータだろうが関係ない。
  2. おお元の ProjectID_ActionForm の $form_template に全部パラメータを書き出しちゃう。

さて。
そんなことを踏まえながらもっかいアプリケーションの設計をしてみようと思いました。

*1:もちろん過信は禁物ですが

*2:その辺自分で規約決めてる人はそんなことないんでしょうけど