[CakePHP]find(“list”)のセレクトボックスに空要素(選択してください)を追加

Written by uechoco 9月 22
この記事を読む時間:155くらい

CakePHP 1.2で、モデルに対してfind(“list”)すると、セレクトボックスに最適な配列を返してくれます。CakePHP 1.1だとgenerateList()って呼ばれていたかもしれません。この配列をそのままViewにsetしてinputタグを作ると、セレクトボックスを簡単に作ってくれますが、いわゆる「選択してください」っていう空要素を吐いてはくれません。

「選択してください」を吐くためにわざわざ配列をarray_merge()しなきゃいけないのかなって思っていたのですが、そこは親切フレームワーク。ちゃんと便利な機能があります。

どうやら、FormHelperのinput()メソッドの第2引数の$optionsに、emptyという要素を含めることで簡単に実現できるらしいです。

Controllerでこんな感じにセットして、
[phpcode]
$this->set(‘hoge_list’, $this->Hoge->find(‘list’));
[/phpcode]
Viewでこんな感じに使います。
[phpcode]
input(‘hoge_id’, array(‘options’ => $hoge_list, ‘empty’ => ‘選択してください’)); ?>
[/phpcode]
すると、選択ボックスの最初に以下のオプションが増えます。

  1. <option value="">選択してください</option>

もちろん、マニュアルにも書いてありますよ。
$options[‘empty’] :: フォーム要素の自動生成 :: フォーム :: 主要なヘルパー :: マニュアル :: 1.2 Collection :: The Cookbook

フレームワークって、使い慣れると最高だけど、使い慣れないと大変ですね。

いちいち調べてたらアプリが期日までに作れねーYo!(’A`)/

がんばろっと。

[SQL]都道府県コードに沿ったSQL

Written by uechoco 9月 21
この記事を読む時間:434くらい

適当なアプリを作ると、都道府県テーブルってよく作るよなってことで、SQLを備忘録で貼っときます。HTMLのセレクトボックスで公開していたり、同じようなSQLを公開している人はもちろん居るのですが、symfonyやCakePHPのようなCoCフレームワークのカラム名のものがなかったので、自分のために貼っときます。一応MySQLばっか使うので、MySQLの出力結果になっています。適当にENGINEとか変えれば他でも使えます。もちろん、JIS X 0401に準拠した都道府県コードを使っています。

CREATE文(utf8を想定)

  1. DROP TABLE IF EXISTS `prefs`;
  2. CREATE TABLE IF NOT EXISTS `prefs` (
  3.   `id` int(10) unsigned NOT NULL,
  4.   `name` varchar(5) NOT NULL,
  5.   PRIMARY KEY  (`id`)
  6. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

INSERT文

  1. INSERT INTO `prefs` (`id`, `name`) VALUES
  2. (1, '北海道'),
  3. (2, '青森県'),
  4. (3, '岩手県'),
  5. (4, '宮城県'),
  6. (5, '秋田県'),
  7. (6, '山形県'),
  8. (7, '福島県'),
  9. (8, '茨城県'),
  10. (9, '栃木県'),
  11. (10, '群馬県'),
  12. (11, '埼玉県'),
  13. (12, '千葉県'),
  14. (13, '東京都'),
  15. (14, '神奈川県'),
  16. (15, '新潟県'),
  17. (16, '富山県'),
  18. (17, '石川県'),
  19. (18, '福井県'),
  20. (19, '山梨県'),
  21. (20, '長野県'),
  22. (21, '岐阜県'),
  23. (22, '静岡県'),
  24. (23, '愛知県'),
  25. (24, '三重県'),
  26. (25, '滋賀県'),
  27. (26, '京都府'),
  28. (27, '大阪府'),
  29. (28, '兵庫県'),
  30. (29, '奈良県'),
  31. (30, '和歌山県'),
  32. (31, '鳥取県'),
  33. (32, '島根県'),
  34. (33, '岡山県'),
  35. (34, '広島県'),
  36. (35, '山口県'),
  37. (36, '徳島県'),
  38. (37, '香川県'),
  39. (38, '愛媛県'),
  40. (39, '高知県'),
  41. (40, '福岡県'),
  42. (41, '佐賀県'),
  43. (42, '長崎県'),
  44. (43, '熊本県'),
  45. (44, '大分県'),
  46. (45, '宮崎県'),
  47. (46, '鹿児島県'),
  48. (47, '沖縄県');

一応HTMLの<select>タグ形式

  1. <select name="pref_id">
  2.   <option value="1">北海道</option>
  3.   <option value="2">青森県</option>
  4.   <option value="3">岩手県</option>
  5.   <option value="4">宮城県</option>
  6.   <option value="5">秋田県</option>
  7.   <option value="6">山形県</option>
  8.   <option value="7">福島県</option>
  9.   <option value="8">茨城県</option>
  10.   <option value="9">栃木県</option>
  11.   <option value="10">群馬県</option>
  12.   <option value="11">埼玉県</option>
  13.   <option value="12">千葉県</option>
  14.   <option value="13">東京都</option>
  15.   <option value="14">神奈川県</option>
  16.   <option value="15">新潟県</option>
  17.   <option value="16">富山県</option>
  18.   <option value="17">石川県</option>
  19.   <option value="18">福井県</option>
  20.   <option value="19">山梨県</option>
  21.   <option value="20">長野県</option>
  22.   <option value="21">岐阜県</option>
  23.   <option value="22">静岡県</option>
  24.   <option value="23">愛知県</option>
  25.   <option value="24">三重県</option>
  26.   <option value="25">滋賀県</option>
  27.   <option value="26">京都府</option>
  28.   <option value="27">大阪府</option>
  29.   <option value="28">兵庫県</option>
  30.   <option value="29">奈良県</option>
  31.   <option value="30">和歌山県</option>
  32.   <option value="31">鳥取県</option>
  33.   <option value="32">島根県</option>
  34.   <option value="33">岡山県</option>
  35.   <option value="34">広島県</option>
  36.   <option value="35">山口県</option>
  37.   <option value="36">徳島県</option>
  38.   <option value="37">香川県</option>
  39.   <option value="38">愛媛県</option>
  40.   <option value="39">高知県</option>
  41.   <option value="40">福岡県</option>
  42.   <option value="41">佐賀県</option>
  43.   <option value="42">長崎県</option>
  44.   <option value="43">熊本県</option>
  45.   <option value="44">大分県</option>
  46.   <option value="45">宮崎県</option>
  47.   <option value="46">鹿児島県</option>
  48.   <option value="47">沖縄県</option>
  49. </select>

symfony系のYAML定義(symfony的にはテーブル名の最後のsはつけない方が一般的かな?)

  1. propel:
  2.   prefs:
  3.     _attributes: { phpName: Prefs }
  4.     id:
  5.     name: { type: VARCHAR, size: '5', required: true, defaultValue: '' }

そのうちフレームワーク毎のモデルクラスとかも貼っておこうかな。

[Mac]netatalkの.AppleDoubleでsymfonyコマンドがつまずく時がある

Written by uechoco 9月 13
この記事を読む時間:819くらい

タイトルでもわかるとおり、非常に限定的な環境でsymfonyを使ったときにハマってしまったので、今後、私と同じようなマニアックな環境でハマってしまった人がググってくれることを期待して備忘録を残します。

さて、私はMac OS X上にVMware Fusion 2を導入していて、会社での開発をVM上のCentOS 5で行っています。開発ではMacのCocoaに対応したEclipse 3.5を主にしようしています。EclipseでVM上のファイルを直接読み書きするため、netatalkというMac版sambaとも言えるソフトウェアをCentOSに導入して、MacとLinux間の共有を行っています。ここら辺のお話は、以前3回に渡って書いたnetatalk導入のブログの記事を参照してもらえればと思います。

Mac OS Xでで外部ストレージ(NFS)などを用いるとき、ファイルのメタ情報を保存するために、netatalkでは.AppleDoubleというフォルダを各フォルダごとに生成し、そのフォルダの中に元ファイル名と同名のファイル名でメタ情報を格納します。※WikipediaのAppleSingleにAppleDoubleについて記載があります。netatalkではnoadoubleというオプションがあり、「必要なければ.AppleDoubleを作らない」という設定にすることができるのですが、必要ある場合は当然作成されてしまいます。例えば、Eclipseからアクセスして保存とかをすると、.AppleDoubleが作られてしまうような気がします。

CentOS上にsymfonyを展開してMacからターミナルで操ろうとしたとき、基本的にはsymfonyのあの深いフォルダ階層のすべてに.AppleDoubleが生成されてしまうということです。そこでこまったのがsymfonyコマンド。propel:build-xxxとかやろうとすると、どうも.AppleDoubleのせいでうまくいかないことがあります。

例えばpropel:build-model
[shcode]
[ueno@localhost project]$ ./symfony propel:build-model
Unable to parse file “/path/to/project/config/.AppleDouble/schema.yml”: Unable to parse line 1 (
[/shcode]
なぜか.AppleDoubleフォルダ内のshema.ymlがパースできないと言われてしまいます。前述の通り、.AppleDoubleフォルダの中に元ファイル名と同名のメタファイルを生成しますので、もしかしたらschema.ymlという名前に反応してしまったのかもしれません。一応propel:build-modelのヘルプを見てみましょう。
[shcode]
[ueno@localhost project]$ ./symfony help propel:build-model
Usage:
symfony propel:build-model [–phing-arg=”…”]

Aliases: propel-build-model

Options:
–phing-arg Arbitrary phing argument (multiple values allowed)

Description:
The propel:build-model task creates model classes from the schema:

./symfony propel:build-model

The task read the schema information in config/*schema.xml and/or
config/*schema.yml from the project and all installed plugins.

You mix and match YML and XML schema files. The task will convert
YML ones to XML before calling the Propel task.

The model classes files are created in lib/model.

This task never overrides custom classes in lib/model.
It only replaces files in lib/model/om and lib/model/map.
[/shcode]
検索条件はconfig/*schema.ymlと書いてありますので、フォルダも引っかかってしまうようです。

で解決策はどうするのか?propel:build-xxx系のコマンドなどでは、symfonyライブラリの中に含まれるsfFinder.class.phpというユーティリティを利用しています。この中に、指定されたルールに基づいて、ファイルやディレクトリを検索するというin()メソッドがあるのですが、この中で、バージョン管理ソフトのディレクトリを無視するようなプログラムの掛かれば部分があります。symfony 1.2.8のlib/symfony/util/sfFinder.class.phpの341行目付近です。
[phpcode]
/**
* Searches files and directories which match defined rules.
*
* @return array list of files and directories
*/
public function in()
{
$files = array();
$here_dir = getcwd();

$finder = clone $this;

if ($this->ignore_version_control)
{
$ignores = array(‘.svn’, ‘_svn’, ‘CVS’, ‘_darcs’, ‘.arch-params’, ‘.monotone’, ‘.bzr’, ‘.git’, ‘.hg’);

$finder->discard($ignores)->prune($ignores);
}
[/phpcode]
svnやらcvsやらgitやらのメタ情報を保存するフォルダの除外指定が列挙されています。ならばここにAppleDoubleをいれればいいんでないか?ということで、修正多野がこちら
[phpcode]
if ($this->ignore_version_control)
{
$ignores = array(‘.svn’, ‘_svn’, ‘CVS’, ‘_darcs’, ‘.arch-params’, ‘.monotone’, ‘.bzr’, ‘.git’, ‘.hg’, ‘.AppleDouble’);

$finder->discard($ignores)->prune($ignores);
}
[/phpcode]
symfonyのコアを書き換えるのはどうかと思ったのですが、この設定を付け加えるだけでnetatalk環境でのsymfonyコマンドが問題なく使えるようになったので開発が進みそうです。

まぁ、こんな環境でsymfony使う人はなかなか居ないと思いますが。。。