HABTM 関係で Ransack を使用した経験がある人がいるかどうか疑問に思っています。私のアプリにphotos
は、habtm 関係があるものがありterms
ます (用語はタグのようなものです)。私が経験していることの簡単な説明は次のとおりです。
写真 1 と写真 2 の 2 枚の写真があります。次の用語があります。
写真1:A、B、C
写真2:A、B、D
私はランサック フォームを作成し、次のようにすべての用語の検索フォームにチェックボックスを作成しました。
- terms.each do |t|
= check_box_tag 'q[terms_id_in][]', t.id
次を使用q[terms_id_in][]
し、「A、C」をチェックすると、結果は写真 1 と写真 2 になります。写真 1 のみが必要です。A と C を要求したためです。このクエリでは、B と D は気にしませんが、必要です。 A と C の両方が特定の結果に存在する必要があります。
q[terms_id_in_all][]
どちらの写真にも A と C しか含まれていないため、使用した場合、結果は nil です。または、おそらく、結合ごとに用語が 1 つしかないため、A と C の両方に一致する結合はありません。
さまざまなものを使用してq[terms_id_eq][]
も結果が得られないため、この場合はうまくいかないと思います。
では、habtm 結合が与えられた場合、与えられた値以外を無視して、与えられた値に一致するモデルをどのように検索するのでしょうか?
または、Ransack に慣れていない Rails/SQL の専門家の場合、habtm 結合を使用するモデルについて説明したような検索フォームを作成するには、他にどのようにすればよいでしょうか?
更新:関連する質問への回答に従って、これに正しく一致する Arel クエリを作成するところまで来ました。どういうわけか、Arelノードをランサッカーとして、またはcdesrosiersが指摘したように、カスタム述語として使用できるはずですが、これまでのところ、私はそれを機能させていません.
その答えに従って、次のランサック初期化子をセットアップします。
Ransack.configure do |config|
config.add_predicate 'has_terms',
:arel_predicate => 'in',
:formatter => proc {|term_ids| Photo.terms_subquery(term_ids)},
:validator => proc {|v| v.present?},
:compounds => true
end
...そして、写真で次のメソッドをセットアップします。
def self.terms_subquery(term_ids)
photos = Arel::Table.new(:photos)
terms = Arel::Table.new(:terms)
photos_terms = Arel::Table.new(:photos_terms)
photos[:id].in(
photos.project(photos[:id])
.join(photos_terms).on(photos[:id].eq(photos_terms[:photo_id]))
.join(terms).on(photos_terms[:term_id].eq(terms[:id]))
.where(terms[:id].in(term_ids))
.group(photos.columns)
.having(terms[:id].count.eq(term_ids.length))
).to_sql
end
残念ながら、これはうまくいかないようです。terms_subquery
は正しい SQLを生成しますが、の結果Photo.search(:has_terms => [2,5]).result.to_sql
は"SELECT \"photos\".* FROM \"photos\" "