Rails фильтрует записи через has_many
Я пытаюсь найти модель элемента с фильтром по имени жанры, которые связаны через has_many.
Моя проблема в том, что когда я выбираю два или более жанра, он также выбирает записи, которые содержат только один жанр.
Пример: есть два жанра: "Экшн" и "Приключение". Запись A имеет жанр Action, а запись B имеет оба жанра. Выбрав оба флажка жанра на мой взгляд, записи, возвращаемые Rails, включают в себя как записи A и B, в то время как это должна была быть только запись B.
Это мой оператор фильтра под контроллером
//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 %>
1 ответ
Причина, по которой это не работает, в том, что 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
в параметрах.