Rails 3ActiveRecordクエリインターフェイスで問題が発生しています。ルックアップテーブル(lookups)、メインテーブル(through_references)、およびthrough_tablesと呼ばれるthrough/joinテーブルがあります。したがって、これは、has_many:throughを使用して設定したHABTM構成です。
更新:ここで特に注意するのは、これらの結合を行うとき、レコードのフィルタリングを提供するためにIDで結合していることです。これはActiveRecordクエリインターフェイスでは機能しないようです。私の苦難の残酷な詳細を見たくない場合は、スキップして以下の私の回避策を見ることができます。
また、いくつかのメインアイテム(through_referencesテーブル)にルックアップアイテムの任意の組み合わせを含めることができ、チェックボックスを介して関連するルックアップアイテムをクリックできるようにする必要があります。
コードをgithubに投稿しました。githubのソースコードについては、さらに多くの説明があります。結果を確認するには、ルックアップのインデックスページに移動します。スキャフォールドコードを使用してレコードを作成する必要があることに注意してください。
また、コードをherokuで実行し、さらに説明と例を示します。
class Lookup < ActiveRecord::Base
has_many :fk_references
has_many :through_tables
has_many :through_references, :through => :through_tables
attr_accessible :name, :value
end
class ThroughTable < ActiveRecord::Base
belongs_to :through_reference
belongs_to :lookup
attr_accessible :description, :through_reference_id, :lookup_id
end
class ThroughReference < ActiveRecord::Base
has_many :through_tables
has_many :lookups, :through => :through_tables
attr_accessible :description
end
すべてのルックアップアイテムとそれに対応するメインアイテムのリストが必要な場合は、「ルックアップ」テーブルとメインアイテム(through_references)テーブルを左に結合できます。対応するSQL:
SELECT * FROM lookups
LEFT OUTER JOIN through_tables ON (lookups.id = through_tables.lookup_id AND through_tables.through_reference_id = 1)
LEFT OUTER JOIN through_references ON through_references.id = through_tables.through_reference_id
ORDER BY lookups.id
返されたレコード:
1;“Lookup Item 1”;“1”;“2012-06-06 17:14:40.819791”;“2012-06-06 17:14:40.819791”;1;1;1;“Main Item 1 has Lookup item 1”;“2012-06-06 17:17:31.355425”;“2012-06-06 17:17:31.355425”;1;“Main Item 1”;“2012-06-06 17:16:30.004375”;“2012-06-06 17:16:30.004375”
2;“Lookup Item 2”;“2”;“2012-06-06 17:14:59.584756”;“2012-06-06 17:14:59.584756”;;;;“”;“”;“”;;“”;“”;“”
3;“Lookup Item 3”;“3”;“2012-06-06 17:15:14.700239”;“2012-06-06 17:15:14.700239”;2;1;3;“Main Item 1 has Lookup item 3”;“2012-06-06 17:17:53.169715”;“2012-06-06 17:17:53.169715”;1;“Main Item 1”;“2012-06-06 17:16:30.004375”;“2012-06-06 17:16:30.004375”
これは私が期待したことです。
===カスタム左結合を使用したアクティブレコードクエリインターフェイス
Lookup.joins(“LEFT OUTER JOIN through_tables ON (lookups.id = through_tables.lookup_id AND through_tables.through_reference_id = 1)” ).includes(:through_references).order(‘lookups.id’)
Active Recordクエリインターフェイスから返されるもの(Active Record階層を下に移動することに注意してください):
Lookup ID Lookup Name Lookup Value Through Table ID Through Table Description Main Item ID Main Item Description
1 Lookup Item 1 1 1 Main Item 1 has Lookup item 1 1 Main Item 1
1 Lookup Item 1 1 3 Main Item 2 has Lookup item 1 2 Main Item 2
2 Lookup Item 2 2 4 Main Item 2 has Lookup item 2 2 Main Item 2
3 Lookup Item 3 3 2 Main Item 1 has Lookup item 3 1 Main Item 1
これは私が期待したものではありません。
ここにあるのは、単純な左結合(AND句なし)と同じです。これは、AND句がActiveRecordクエリインターフェイスで無視されていることを示しています。
===find_by_sqlアプローチを使用したアクティブレコードクエリインターフェイス
Lookup.find_by_sql("SELECT * FROM lookups LEFT OUTER JOIN through_tables ON (through_tables.lookup_id = lookups.id AND through_tables.through_reference_id = 1) LEFT OUTER JOIN through_references ON through_references.id = through_tables.through_reference_id ORDER BY lookups.value, through_references.id" )
Active Recordクエリインターフェイスから返されるもの(Active Record階層を下に移動することに注意してください)::
Lookup ID Lookup Name Lookup Value Through Table ID Through Table Description Main Item ID Main Item Description
1 Lookup Item 1 1 3 Main Item 2 has Lookup item 1 2 Main Item 2
1 Lookup Item 1 1 1 Main Item 1 has Lookup item 1 1 Main Item 1
Lookup Item 2 2 No through_tables entry
1 Lookup Item 3 3 3 Main Item 2 has Lookup item 1 2 Main Item 2
1 Lookup Item 3 3 1 Main Item 1 has Lookup item 1 1 Main Item 1
ここでの結果はクレイジーです!
これはバグですか、これは意図された効果ですか、それとも何かが足りませんか?
2つの結果セットを生成し、それらをコードでマージすることなく、これを行うためのクリーンな方法があることを願っています。