Rails AR + Mysql - 排除电影类型不能按预期工作

时间:2012-12-30 19:46:53

标签: mysql ruby-on-rails ruby activerecord squeel

假设我有一个带流派的电影数据库,我想展示除了某些特定类型的所有电影。我已经建立了协会,工作得很好。

为了做到这一点,我遇到了名为Squeel的宝石,并写了这段代码

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条件看起来甚至都不适用,因为我看到它与否都没有区别。

查看截图: Mysql terminal output showing work of sql query

有没有人有任何想法,为什么它不起作用,我应该从哪里开始挖掘?

非常感谢所有帮助。

2 个答案:

答案 0 :(得分:1)

问题在于逻辑,而不是sql。使用“OR”逻辑,您希望线条满足任何条件,因此对于您的查询,您将获得ID为10的行,因为10!= 12.使用WHERE IN - 精细方式

答案 1 :(得分:0)

使用命名范围

解决了这个问题
scope :excluding_genres, 
  lambda { |genres| { 
    :conditions => 
       ['movies.id NOT IN 
       (SELECT movies.id FROM movies 
        LEFT JOIN movie_genres ON movies.id = movie_genres.movie_id 
        WHERE movie_genres.genre_id IN (?))', genres] 
  }}