我有Users
和Languages
个表格,由LanguagesUsers
加入。 LanguagesUsers
存储language_id
,user_id
和level
。
Users
可以无限制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
答案 0 :(得分:3)
我认为我不仅仅知道最近添加到ActiveRecord的&&
和||
的额外用法。我认为那是你的问题。
@users
和User.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)