Catalyst でのモデルとロジック
分けたほうがいいよー!という話を最近よく聞く(読む)ので、分けるようにした。
とりあえず Catalyst での config やら model はそのまま使いたいけれど、CLI とかではどうするの?って話になるので、その辺もくそかっこわるいけどなんとかできるように。
具体的には、Catalyst::Model::DynamicAdaptor をほんのちょっと拡張して、Catalyst::Model::DynamicAdaptor::Lazy というものを作った。
実際に使う場合には、それをベースクラスに持つ MyApp::Model::Logic なんてのをこさえて、MyApp::Logic::Hoge やら MyApp::Logic::Fuga なんてものを坦々と作ると。
で、Catalyst で動作している場合は、DynamicAdaptor そのまんまに $c->model('Logic::Hoge') 出来るし、Catalyst じゃない場合は、MyApp::Model::Logic のカスタムコンストラクタに config と schema を渡せばいいと。具体的にはこんな感じに使えるように。
my $config = LoadFile(file($Bin, '..', 'myapp.yml')); # とりあえず YAML 使ってるので my $schema = MyApp::Model::DBIC->new; my $l = MyApp::Model::Logic->new_with_nocatalyst('MyApp::Logic', $config, $schema); print $l->logic('Hoge')->say;
安直で、素晴らしくかっこわるい。正直このまま実用する気はない。
SQL を DBIC でうまく使う
DBIC Custom ResultSource for Arbitrary SQL
So you haven't figured out how to write a complex query in DBIC yet? No worries, DBIC will allow you to write that query in SQL. To do so one:
- Defines a custom ResultSource based on an existing one.
- Pass the new ResultSource's name method the raw SQL.
- Register the new ResultSource with your Schema.
こんな方法は知らなかった。あとでやってみる。
Cookbook にも載ってた。
ジェフサポになってしまいそう
この盛り上がりっぷりはたまらん。
Catalyst::Plugin::Session の flash ではまった
Store::DBIC を使ってるのだけど、flash が使えなくてはまった。
そのとき出たログは、sessions テーブル の row が見つからないから update できないよーってもの。
row が見つからないっていうから id の照合順序とかそのへんを疑ったりしても何も変わらず。
で、もう一度 Manual とかを見直したら、sessions テーブルの構造がちょっとだけ違ってた。
俺が作った sessions テーブルは
CREATE TABLE `sessions` ( `id` char(72) NOT NULL, `session_data` text NOT NULL, `expires` int(10) unsigned NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
こんなんで、正しくは、
CREATE TABLE `sessions` ( `id` char(72) NOT NULL, `session_data` text, `expires` int(11) default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
こう。phpMyAdmin で出力してるから余計な情報がくっついちゃってるけれども。
で、最初の例でも通常のセッション管理だけなら問題ない(多分。使えてたし)。けれど、flash を使う時に問題が発生する。
なぜなら flash データを保持するときは、expires に値を入力しないから。
で、expires に値が無いため、デフォルト値の 0 が設定される。すると、$c->delete_expired_sessions を実行した場合に期限切れとして flash データが削除されてしまうのだ。これが正しいほうの例であれば、expires には 0 ではなく null が設定され、その場合は delete_expired_sessions の対象ではなくなる。そういうことみたい。
ということで、つまらないミスのせいではまったけど、繰り返さないようにメモしとこう。
「あたし彼女」をまねた文章の多さに
頭がくらくらする。
やめてほしい。いい大人が悪のりして「みたいな」とか書くのは。
Google Chrome の使い道
今のところ、メインのブラウザとしてではなく、ショートカットをいくつか作って、単体アプリケーションみたいな感じで使ってる。
たとえばこんなショートカット。
- 社内グループウェア
- タイムカード的な機能を使ってるので、Firefox だと起動が遅くてめんどくさい。
- 社内用 Google Calendar
こうやって限定的なサイトのショートカットを作っていけるのは便利だしとってもうれしい。
で、自作のコマンドラインランチャーでそれぞれを簡単に起動できるようにすれば完成。