Rails, Ransack: Como pesquisar o relacionamento HABTM para "todas" correspondências em vez de "any"

Eu estou querendo saber se alguém tem experiência usando Ransack com relacionamentos HABTM. Meu aplicativo temphotos que têm uma relação de habtm comterms (termos são como tags). Aqui está uma explicação simplificada do que estou experimentando:

Eu tenho duas fotos: Foto 1 e Foto 2. Eles têm os seguintes termos:

Foto 1: A, B, C

Foto 2: A, B, D

Eu construí um formulário de saque e faço caixas de seleção no formulário de busca para todos os termos, assim:

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

Se eu usar:q[terms_id_in][] e eu verifico "A, C" meus resultados são Foto 1 e Foto 2. Eu só quero Foto 1, porque eu pedi A e C, nesta consulta eu não me importo com B ou D mas eu quero tanto A como C estar presente em um determinado resultado.

Se eu usarq[terms_id_in_all][] meus resultados são nulos, porque nenhuma foto inclui apenas A e C. Ou, talvez, porque há apenas um termo por junção, portanto, nenhuma junção corresponde a A e C. Independentemente, quero que apenas a Foto 1 seja retornada.

Se eu usar qualquer variedade deq[terms_id_eq][] Eu nunca obtenho nenhum resultado, então não acho que funcione nesse caso.

Então, dada uma junção habtm, como você procura por modelos que correspondam aos valores dados enquanto ignora valores não dados?

Ou, para qualquer rails / sql gurus que não esteja familiarizado com o Ransack, de que outra forma você poderia criar um formulário de busca como estou descrevendo para um modelo com uma associação habtm?

Atualização: pora resposta à questão relacionada, Agora eu comecei a construir uma consulta Arel que corresponde corretamente a isso. De alguma forma você deveria ser capaz de usar os nós Arel como invasores, ou como cdesrosier apontado, como predicados personalizados, mas até agora eu não consegui isso funcionando.

Por essa resposta, eu configurei o seguinte inicializador de saqueador:

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

... e depois configure o seguinte método em 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

Infelizmente isso não parece funcionar. Enquantoterms_subquery produz o SQL correto, o resultado dePhoto.search(:has_terms => [2,5]).result.to_sql é apenas"SELECT \"photos\".* FROM \"photos\" "

questionAnswers(1)

yourAnswerToTheQuestion