[Catalyst] TTでDBICのhas_manyなメソッドを使う
よくわからない表題ですが要は・・・
MyApp::Schema::TopicsとMyApp::Schema::Commentsが1:nの関係にあるとして
package MyApp::Schema::Topics;
use strict;
__PACKAGE__->has_many('comments' => 'MyApp::Schema::Comments');
1;
こんなアクションで
sub list : Local {
my ( $self, $c ) = @_;
my $topics = $c->model('Topics')->search({});
$c->stash->{topics} = $topics;
$c->stash->{template} = 'list.tt';
}
TTで素でやる場合
<html>
<body>
<ul>
[% WHILE (topic = topics.next) %]
<li>
[% topic.title %]
: comments([% topic.comments.size ? topic.comments.size : 0 %])
</li>
[% END %]
</ul>
</body>
</html>
とかするのかなぁと。
何を言いたいかというと、TTでhas_manyで定義した子オブジェクトの結果一覧を取得するメソッド(ここではcomments)にアクセスするとイテレーターではなく配列のリファレンスとして扱われるので大変面倒。
で、こうするといい感じ。
<html>
<body>
<ul>
[% WHILE (topic = topics.next) %]
<li>
[% topic.title %]
: comments([% topic.comments_rs.count %])
</li>
[% END %]
</ul>
</body>
</html>
search_rs同様、_rsをつけるだけで強制的にイテレーター(ResultSet)を返すことができる。
ぶっちゃけしらんかったです。
SELECT COUNT( * ) FROM comments me WHERE ( me.topic_id = ? )
しかも、こんなこともできちゃう。
<html>
<body>
<ul>
[% WHILE (topic = topics.next) %]
<li>[% topic.title %]</li>
: comments([% topic.comments_rs.count %])
<ul>
[% SET comments = topic.comments_rs.search_rs({}{rows => 5}) %]
[% WHILE (comment = comments.next) %]
<li> [% comment.title %]</li>
[% END %]
</ul>
[% END %]
</ul>
</body>
</html>
とっても便利・・・かな。
