私はアプリの小さなバグに取り組んでおり、ここで単純化しようとしています。
私はこの会社モデルを持っています (実際のモデルにはさらに多くの関連付けがありますが、ここに問題が表示されます):
class Company < ActiveRecord::Base
has_many :contacts
def self.search(query, page=1)
companies = includes(:contacts).order("companies.name ASC")
if query.present?
companies = companies.where(%(
companies.name ILIKE :q,
OR contacts.name ILIKE :q
), q: "%#{query}%")
end
companies.paginate(page: page)
end
end
現在、これはほとんどうまく機能しています。唯一の問題は、会社に 2 つ以上の連絡先があり、ユーザーが連絡先の名前の 1 つに基づいて検索する場合です。会社が正しく検出され、オートコンプリート UI に会社が表示されます。ただし、ユーザーがオートコンプリートから会社を選択すると、ドロップダウン リストから連絡先を選択できるはずですが、ドロップダウンにはフィルターで絞り込んだ 1 つの連絡先しか含まれません。会社は検索基準に基づいてフィルタリングする必要がありますが、そのドロップダウンには、ユーザーが選択できる会社の連絡先がすべて含まれている必要があります。
なぜこれを行っているのかはわかっています。それは、クエリが実行された瞬間にレールがすべての関連付けを自動ロードして、すべての関連付けプロパティを取得し、同時にすべての条件を含めることができるためです。
それはselect {every_attribute_from_every_included_table} left outer join {all_included_tables}
一種のクエリを実行していますが、私がやりたいのはこれです:
select companies.* from companies
left outer join contacts <and other included tables> on <join criteria>
where <filter criteria>
次の企業をフィルタリングするには:
select contacts.* from contacts
where company_id IN (<company_ids from previous query>)
include
テーブルもwhere
句に含まれていない場合、通常はどのようにエントリが含まれますか。
Rails はここでマジックを使いすぎているので、特別なマジックではなく、通常のマジックに戻してほしいです! どうやってやるの?または、私が達成しようとしていることを達成するためのより良い方法は何ですか (連絡先名に基づいてフィルタリングしますが、呼び出し時に他の連絡先が含まれるのを止めないでくださいcompany.contacts
)。