即使有更多关联而不是范围要求

时间:2017-11-15 22:47:46

标签: sql ruby-on-rails ruby

我有UsersLanguages个表格,由LanguagesUsers加入。 LanguagesUsers存储language_iduser_idlevelUsers可以无限制LanguagesUsers

我希望得到所有拥有两种语言的用户。我的用户模型中有两个范围:

scope :seeking_proficiency_in, ->(language) {
  joins(:languages_users).where("level < 5 and language_id = ?", language)
}
scope :proficient_in, ->(language) {
  joins(:languages_users).where("level > 4 and language_id = ?", language)
}

我想传递两种语言,并找到同时具有这两种范围的用户。查询是这样的:

@users =
  (User.seeking_proficiency_in(1) && User.proficient_in(2)) ||
  (User.seeking_proficiency_in(2) && User.proficient_in(1))

返回具有两种语言和适当语言级别的所有用户。问题是不包含两种以上语言的用户;仅包括具有两种语言的用户。

即使他们拥有的语言多于给定的两种语言,我怎样才能获得所有用户?

UPDATE 为了给出更多的上下文,这可行,但我觉得有一个简单的,一步两个版本,我不理解:

learning = User.seeking_proficiency_in(1)
fluent = User.proficient_in(2)
matches = learning & fluent

learning = User.seeking_proficiency_in(2)
fluent = User.proficient_in(1)
second_matches = learning & fluent

all_matches = matches + second_matches

1 个答案:

答案 0 :(得分:3)

我认为我不仅仅知道最近添加到ActiveRecord的&&||的额外用法。我认为那是你的问题。

由于@usersUser.proficient_in(2)运算符的工作原理,

&&实际上只是||。见下面的例子

  >> nil && true                            # nil
  >> true && 1                              # 1
  >> [] && 1                                # 1
  >> User.where(id: 1) && User.where(id: 2) # result will be the result of User.where(id: 2)

由于User.where(...)查询返回ActiveRecord::Relation对象,因此返回的值不是假的,因此代码的第二部分(||之后的那部分)永远不会执行。

简而言之,您无法使用&&||来合并ActiveRecord查询。请尝试以下

 inverse = User.seeking_proficiency_in(2).proficient_in(1)
 @users = User.seeking_proficiency_in(1).proficient_in(2).or(inverse)