[CakePHP]$form->inputで行われる自動判別のまとめ

1.1系ではHtmlHelperにあったinputメソッドが、1.2系ではFormHelperに移っています。
使い方としては

<?php echo $form->input('field_name', array('type' => 'textarea' /* テキストエリア指定 */)); ?>

などといった感じで、オプション指定の配列にtypeを指定することで、テキストエリアやセレクトボックスなどの種類を指定できるのですが、単純に

<?php echo $form->input('field_name'); ?>

と、フィールド名の指定をしただけでも、自動的にテキストエリアになったり、セレクトボックスになったりすることがあります。

どんな自動判別をしているのか気になったので、調べて分かったことをまとめてみます。(バージョンはBeta 1.2.0.6311)

type指定がない場合の決定方法
まず、オプション配列にtypeの指定がない場合、以下の流れでtypeが決定されます。

1.オプション配列にoptionsをセットした場合
typeはselectに決定され、、セレクトボックスになります。

<?php echo $form->input('select', array('options' => array('1'=>'イチ', '2'=>'ニー', '3'=>'サン'))); ?>

↓↓↓

2.フィールド名が'psword', 'passwd', 'password' のいずれかの場合
typeはpasswordに決定され、パスワード入力用のテキストボックスになります。

<?php echo $form->input('password'); ?>

↓↓↓

3.上記1、2に該当しない かつ フィールド名がテーブルに存在する場合
DBのカラム型からtypeの値が決定されます。
MySQLとPostgreSQLのいくつかのカラム型で試してみた結果を一覧にしてみました。

MySQLカラム型PostgreSQLカラム型決定されるtype と 出力のスクリーンショット

TINYINT
INT
BIGINT
FLOAT
DOUBLE
VARCHAR

int2
int4
int8
float4
float8
varchar

text

TEXT

text
time

textarea

BOOLEAN

bool

checkbox

DATE

date

date

DATETIME
TIMESTAMP

timestamp

datetime

TIME

time

PostgreSQLのtime型がtextareaになってしまうのは注意が必要かもしれません。
また、カラム型から決定する際にフィールド名がプライマリーキーと一致する場合はtypeはhiddenに決定され、hidden項目になります。

4.フィールド名にモデル名を入れた場合
ここの判定の意図は不明なのですが、typeはselectに決定され、マルチ選択可能なセレクトボックスになります。
例えばPostsControllerのアクションのビューで

<?php echo $form->input('Post', array('options' => array('1'=>'イチ', '2'=>'ニー', '3'=>'サン'))); ?>

とすると

のようになります。
HABTMアソシエーションあたりで使うのでしょうかね?

5.上記1〜4に当てはまらない場合
typeはtextに決定され、テキストボックスになります。

命名規則に沿った配列がビューにセットされているとtypeはselectに変換される
ここは今回調べた中で一番重宝しそうな部分です。
オプション配列にoptionsがセットされていない かつ typeがtext、checkbox、radio、selectのいずれかの場合の話です。
ここでいうtypeはオプション配列で指定したtype、自動判別で決定されたtype、どちらでも構いません。

「命名規則に沿った」の命名規約とは「フィールド名の後ろから'_id'を削り、それを複数形にした名前」になります。

どういうことかというと、あるコントローラーのアクションの中で

<?php
$this->set('users', array('1'=>'one', '2'=>'two', '3'=>'three'));

とセットして、ビューの中で

<?php echo $form->input('user_id'); ?>

とすると、typeはselectに決定され、セレクトボックスになります。

このテクニックはアソシエーションがあるものの編集などで有用だと思います。
実際、アソシエーションのあるモデルについてコントローラーのbakeを行うと、この方法が使われています。

オプション配列にmaxlengthがセットされていない かつ typeがtextの場合
maxlengthにテーブルのカラムの桁数がセットされます。
例えばvarchar(10)のカラムであれば、出力されるテキストボックスにはmaxlength="10"がセットされます。
ここでのtypeもオプション配列で指定したtype、自動判別で決定されたtype、どちらでも構いません。

まとめ
自動判別は便利な反面、ルールを知らないと自分でコントロールできずにハマることが多いので、ルールを押さえてうまく利用していきたいですね。