ジャンルの映画データベースがあり、特定のジャンルを除くすべての映画を表示したいとしましょう。私はすべての関連付けをセットアップし、問題なく動作しています。
これを行うために、Squeelという名前の gem に出会い、このコードを書きました。
movies = Movie.joins(:movie_genres).approved
# This is just an array of id's
included_genres = params[:genres][:included_genres]
excluded_genres = params[:genres][:excluded_genres]
if included_genres
# This works just fine
movies = movies.where(movie_genres: {genre_id: included_genres})
# This works too but IMO MySQL IN operator is faster.
#movies = movies.where{movie_genres.genre_id.eq_any included_genres}
end
if excluded_genres
# Here is where the problems occurs, it generates perfectly nice SQL
# but for some reason it doesn't work as expected.
movies = movies.where{movie_genres.genre_id.not_eq_any excluded_genres}
# If we do it this way, it will only not match those movies
# that have all the selected genres at once, i need to match
# all movies that have atleast one of the inputted genres
#movies = movies.where("genre_id NOT IN (?)", excluded_genres)
#movies = movies.where{movie_genres.genre_id.not_eq_all excluded_genres}
end
movies = movies.group(:id)
ええ、Squeel のおかげで、次の SQL を取得できます。
SELECT `movies`.* FROM `movies`
INNER JOIN `movie_genres` ON `movie_genres`.`movie_id` = `movies`.`id`
WHERE ((`movie_genres`.`genre_id` != 10 OR `movie_genres`.`genre_id` != 12))
GROUP BY `movies`.`id`;
期待どおりに機能するため、ジャンルは含まれていません。
その結果、 where 条件は、それがある場合とない場合に違いが見られないため、適用されないように見えます。
スクリーンショットを参照してください:
なぜそれが機能しないのか、どこから掘り始めるべきなのか、誰にもアイデアはありますか?
すべての助けに感謝します。