7

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\" "

4

1 に答える 1

2

関連する質問に対する私の回答のように定義されたカスタムランサック述語を使用すると、マークアップを簡単に変更するだけで機能するはずです。

- terms.each do |t|
  = check_box_tag 'q[id_has_terms][]', t.id

アップデート

は私が思っていたようには機能しません。また:formatter、Ransack リポジトリが「サブクエリ」について 1 つも言及していないことを考えると、結局のところ、実行しようとしていることに使用できない可能性があります。利用可能なすべてのオプションが使い果たされているように見えるので、モンキー パッチ以外に何もすることがありません。

ランサックをスキップして、アクティブなレコード (または現在の Arel クエリでも) で通常行うように、「写真」テーブルにクエリを実行してみませんか? クエリが機能することは既にわかっています。Ransack を使用することで得られる具体的なメリットはありますか?

于 2012-11-19T23:14:25.907 に答える