8

片側で複数のタイプのオブジェクトを処理できるリンクテーブルがあり、has_manyを使用してこれらのオブジェクトの1つからリンクテーブルに移動する方法を理解できません。

例:リンクテーブルには次のものが含まれます。

id link_id link_table resource_id
1  1       page       3
2  1       page       5
3  2       page       3
4  1       not_page   1

リソース側からの関係の構築は非常に簡単です。

Resource->has_many(links => 'Link', 'resource_id');

しかし、ページ側から対応する関係を取得できませんでした。

Page->has_many(links => 'Link', 'link_id');

not_pageリンクを取得します

Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => 'page'});

'Invalid rel cond val page'エラーが発生します(これは私にとってそれほど驚くことではありませんでした)。

Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => '"page"'});

'Invalid rel condval"page"'エラーが発生します。バックスラッシュを投げても役に立ちませんでした。

DBIx :: Class :: Relationship :: Baseのコメント

条件は、テーブル間の結合のSQL::Abstractスタイルの表現である必要があります

そして、私はそこから次のようなさまざまなオプションを試しました。

Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => {'=', 'page'}});

しかし、まったく成功しませんでした。

常に値'page'を含むページテーブルに別のフィールドを追加した場合、私は行うことができます

Page->has_many(links => 'Link', {'foreign.link_id' => 'self.id', 'foreign.link_table' => 'self.what_table_am_i'});

しかし、それはほとんど最適な解決策ではありません。

リンクテーブルをタイプごとに個別に分割することも可能ですが、これはDBIx :: Classへの適応を検討している既存のプロジェクトであり、テーブルを他の複数のテーブルに分割する方が多い場所もあります。それが価値があるよりも面倒。

4

2 に答える 2

3

必要な引数との関係を呼び出すラッパー メソッドを作成する必要があります。

Page->has_many(__all_links => 'Link', 'link_id');

sub links {
    shift->__all_links({link_table => 'page'});
}

この種の結合ロジックが必要なテーブルが複数ある場合、これを DBIx::Class コンポーネントに変換するのは非常に簡単です。

于 2009-02-23T14:01:57.200 に答える
1

次のように has_many 呼び出しで指定できます。

Page->has_many(links => 'Link', 'link_id',
                    { where => { link_table => 'page'} });

参照: DBIx::Class クックブック

于 2010-08-20T14:29:35.917 に答える