我有 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))
这将返回所有拥有两种语言和相应语言级别的用户。问题是不包括使用两种以上语言的用户;仅包括恰好使用两种语言的用户。
即使他们使用的语言比给定的两种多,我如何才能获得所有用户?
更新 为了提供更多上下文,这会起作用,但我觉得有一个我不理解的简单的一两步版本:
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
最佳答案
我以为我不只是知道最近添加到 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)
关于sql - 即使关联多于范围要求也返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47318635/