Rails, Ransack: Cómo buscar en la relación HABTM "todas" coincidencias en lugar de "cualquiera"

Me pregunto si alguien tiene experiencia en el uso de Ransack con relaciones HABTM. Mi aplicación tienephotos que tienen una relación habtm conterms (Los términos son como etiquetas). Aquí hay una explicación simplificada de lo que estoy experimentando:

Tengo dos fotos: Foto 1 y Foto 2. Tienen los siguientes términos:

Foto 1: A, B, C

Foto 2: A, B, D

Construí un formulario de saqueo, y hago casillas de verificación en el formulario de búsqueda para todos los términos, así:

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

Si uso:q[terms_id_in][] y verifico "A, C" mis resultados son la foto 1 y la foto 2. Solo quiero la foto 1, porque pedí A y C, en esta consulta no me importa B ni D, pero quiero tanto A como C Estar presente en un resultado dado.

Si yo usoq[terms_id_in_all][] mis resultados son nulos, porque ninguna de las fotografías incluye solo A y C. O, quizás, porque solo hay un término por combinación, por lo que ninguna combinación coincide con A y C. Independientemente, quiero que solo se devuelva la foto 1.

Si utilizo alguna variedad deq[terms_id_eq][] Nunca obtengo ningún resultado, así que no creo que funcione en este caso.

Entonces, dada una unión habtm, ¿cómo buscar modelos que coincidan con los valores dados al ignorar los valores no dados?

O, para cualquier gurú de Rails / sql que no esté familiarizado con Ransack, ¿de qué otra manera podría crear un formulario de búsqueda como el que estoy describiendo para un modelo con un enlace habtm?

Actualización: porla respuesta a la pregunta relacionadaAhora he llegado a construir una consulta de Arel que coincide correctamente con esto. De alguna manera se supone que debes poder usar los nodos de Arel como saqueadores, o como señalaron los cdesrosiers, como predicados personalizados, pero hasta ahora no he conseguido que funcione.

Por esa respuesta, configuré el siguiente inicializador de saqueo:

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

... y luego configurar el siguiente método en la foto:

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

Desafortunadamente esto no parece funcionar. Mientrasterms_subquery produce el SQL correcto, el resultado dePhoto.search(:has_terms => [2,5]).result.to_sql es solo"SELECT \"photos\".* FROM \"photos\" "

Respuestas a la pregunta(1)

Su respuesta a la pregunta