わかりました、DBIx::Class は初めてです。次のように、1対多の関係が設定されています。
User -> has_many -> Addresses
わかりました。次のように、クエリを実行して、JOIN されたテーブルのプリフェッチと呼ぶことができます。
Foo::DBIC->storage->debug(1); # output SQL to STDOUT
my $user = Foo::DBIC->resultset('Users')->search({}, {
prefetch => [ 'addresses' ],
join => [ 'addresses' ],
rows => 1
})->single;
for my $address ($user->addresses->all) {
say $address->zip_code;
}
2 つのテーブル、1 つの SQL クエリ (デバッグで検証)。すべては順調です。
しかしここで、Foo::DBIC::Result::Users に、特定の基準に基づいてアドレスのサブセットを返すオーバーロード メソッドを 1 つまたは 2 つ書きたいとします。Users クラスに追加したものは次のとおりです。
sub home_addresses {
my $self = shift;
return $self->search_related('addresses', { address_type => 'home' });
}
sub business_addresses {
my $self = shift;
return $self->search_related('addresses', { address_type => 'business' });
}
これらのオーバーロードは次のように呼び出すことができ、機能します。
for my $address ($user->home_addresses->all) {
say $address->zip_code;
}
ただし、これは結合をプリフェッチしたという事実を無視し、ADDITIONAL QUERIES を実行します (何もプリフェッチして結合していないかのように)。
そこで、私の質問は次のとおりです。関連テーブルのサブセットを返すが、既にプリフェッチされた結合を使用するオーバーロード メソッドを定義するにはどうすればよいですか? (プリフェッチに WHERE 句を追加するだけです)...
私の問題は、関連するテーブルのサブセットを返すオーバーロードされたメソッドが多数ある場合、クエリ数が急増する可能性があることです。特にループ内から呼び出している場合。
もちろん、これを行うには醜い理由があります。私の実際のスキーマは、Users や Addresses よりもずっと、ずっと、ずっと、ぐちゃぐちゃです。
ありがとう!