2

テーブルを select/group-by クエリ (同じテーブルを含む) に結合する必要があり、Arel を使用して実行したいと考えています。

私は自分自身である:phenotypeswhich areの表を持っています。その結果、表現型とオルソグループの関係は多対多になります。has_and_belongs_to_many :geneshas_and_belongs_to_many :orthogroups

特定の表現型に関連付けられたすべてのオルソグループを取得する 2 つのスコープ (オルソグループ上) があります。

  scope :with_phenotype, lambda { |phenotype_id|
    where("observations.phenotype_id = ?", phenotype_id).
      joins("inner join orthologies on (orthologies.orthogroup_id = orthogroups.id) inner join observations on (observations.gene_id = orthologies.gene_id)")
  }

  scope :with_associated_gene_ids_for_phenotype, lambda { |phenotype_id|
    with_phenotype(phenotype_id).
      select("orthogroups.id, array_agg(distinct observations.gene_id) as associated_gene_ids").
      group("orthogroups.id")
  }

したがって、実行Orthogroup.with_associated_gene_ids_for_phenotype(48291)すると、オルトグループ ID と、それらを表現型にリンクする遺伝子のテーブルが返されます。

そのようなものはすべて正常に機能します。

orthogroups.*問題は、遺伝子のリストが基本的に私の Orthogroup ActiveRecord モデルの追加フィールドのようになるように、残りを取得して 2 番目のスコープの結果に結合したいということです。

おおよそ、次のようなものです。

SELECT   o1.*, o_genes.associated_gene_ids
FROM     orthogroups o1
INNER JOIN (
  SELECT    o2.id, array_agg(DISTINCT obs.gene_id) AS associated_gene_ids
  FROM orthogroups o2
  INNER JOIN orthologies ortho ON (ortho.orthogroup_id = o2.id)
  INNER JOIN observations obs ON (ortho.gene_id = obs.gene_id)
  WHERE obs.phenotype_id = ? GROUP BY o2.id
) AS o_genes
ON (o1.id = o_genes.id);

これで、そのクエリが機能するように見えます。しかし、これらの遺伝子を取得するために、Orthogroup テーブルを独自のスコープに直接結合する方法を見つけたいと思っています。

SQL を使用する方が簡単かもしれませんが、Arel を使用すると簡単な方法があるはずです。同様の質問をいくつか見つけましたが、答えがあるようには見えません。

私が見つけた最も近い解決策はこれです:

def self.orthogroups phenotype_id
  Orthogroup.select("orthogroups.*, o_genes.associated_gene_ids").
    joins(Arel.sql("inner join (" + Orthogroup.with_associated_gene_ids_for_phenotype(phenotype_id).to_sql + ") AS o_genes ON (o_genes.id = orthogroups.id)"))
end

出力された SQL は、テーブル「orthogroups」を 2 つのコンテキストで使用しており、これが心配でした。ただし、結果のスポット チェックは、クエリが正しいことを示唆しています。

それでも、これは私が望んでいたエレガントなソリューションではありません。ぎこちなくこれを行うことは可能です"inner join (...)"か?

4

1 に答える 1

0

コードを一目見ただけで、同じ名前の関係があるため、メソッドとローカル変数「orthogroups」の名前を別のものに変更しようとしましたか?

于 2011-01-03T12:16:27.737 に答える