sql - 即使关联多于范围要求也返回

标签 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))

这将返回所有拥有两种语言和相应语言级别的用户。问题是不包括使用两种以上语言的用户;仅包括恰好使用两种语言的用户。

即使他们使用的语言比给定的两种多,我如何才能获得所有用户?

更新 为了提供更多上下文,这会起作用,但我觉得有一个我不理解的简单的一两步版本:

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/

相关文章:

c# - 如何手动创建嵌套的 POST 参数? (例如,我正在 .Net 中创建请求以联系 Rails 后端)

ruby-on-rails - 将 libsass 与 Rails Assets 管道一起使用

javascript - 关于 javascript 禁用按钮的光标样式的问题

ruby-on-rails - 如何根据日期作为数据库中的列的确切年份过滤用户?

mysql - SQL:如何获取计数值的 sum()

sql - 文件系统中目录路径的分层/树数据库

mysql - 为 JSON API 构建 SQL 请求

sql - 如何在 XML 列上使用 xpath 来选择行?

ruby - 为什么我所有的看跌期权都返回=>nil?

ruby - 为什么 shell 输出经常在其输出中使用 `mixed_characters'?