0

Я пытаюсь найти модель элемента с фильтром, названным жанрами, которые связаны через has_many через.Записи фильтра рельсов has_many через

Моя проблема в том, когда я выбираю два жанра или более, он также выбирает записи, которые содержат только один жанр.

Пример: Существует два жанра «Действие и приключение». Запись A имеет жанр Action и Record B имеет оба жанра. Выбирая оба жанра checkboxs на мой взгляд, записи, возвращаемые Rails включает как запись A & В то время как он должен был лишь записи Б.

Это мое заявление фильтра под контроллер

//This is under controller 
    @item = Item.includes(:genres).where('genres.id' => params['genre_ids']) 
    // This is under my view 
    <%= simple_form_for Item.new, :method => :get, url: search_path do |f| %> 

     <% Genre.all.each do |sc| %> 
      <div> 
       <label> 
       <%= check_box_tag 'genre_ids[]',sc.id %> 
       <span style="font-weight:normal;"><%= sc.name %> </span> 
      </label> 
      </div> 
      <% end %> 

    <% end %> 

ответ

0

Причина, по которой он не работает, заключается в SQL, который создается из вашего выражения. where('genres.id' => [1, 2, 3]) дает вам SELECT ... WHERE genres.id IN (1,2,3), который по существу является OR-выражением.

Чтобы исправить это, вам необходимо отфильтровать количество выбранных жанров в Ruby или SQL. Я бы сделал это с SQL следующим образом:

genre_ids = params['genre_ids'] 
items = Item.joins(:genres).where('genres.id' => genre_ids).group('items.id').having("count(*) = #{genre_ids.size}") 

С помощью этого вы выберете элементы с точным заданным набором жанров. Не забудьте обработать случай с пустым genre_ids в параметрах.

+0

Я не могу проверить код прямо сейчас, но для будущих ссылок о SQL, (я использую PostgresSQL), где я могу прочитать об этих общих выражениях, которые обычно используются для фильтрации записей? – Wraithseeker

+0

Что вы подразумеваете под «общими выражениями»? Это всего лишь немного логики - поскольку в результате вы получаете запись по жанру (да, по жанру, а не по элементу), вы группируете их по идентификатору элемента, а затем удаляете число с количеством записей меньше, чем количество идентификаторов жанра вы предоставили. Таким образом, вы получаете записи только с точным набором жанров. –