Rails/SQL 结合 rails 范围的条件
Rails/SQL combine where conditions for rails scope
我想获得除 [30, 54] 和 language_id 之外 language_id 的项目总数:无
LOCALES = {
non_arabic_languages: {
id: [30, 54]
}
}
scope :non_arabic_languages, -> { where.not(language_id: LOCALES[:non_arabic_languages][:id]) || where(language_id: nil) }
这个例子可以预见returns第一部分,所以我只得到非阿拉伯语的项目。 && 也有问题。我该如何组合它?我们将感谢您的建议!
您陷入了一个常见的陷阱,您将 Ruby 中的逻辑操作与通过 ActiveRecord 查询接口实际创建 SQL 混淆了。
使用 ||
将 return 第一个真实值:
where.not(language_id: LOCALES[:non_arabic_languages][:id]) || where(language_id: nil)
这是 return 由 where.not(language_id: LOCALES[:non_arabic_languages][:id])
编辑的 ActiveRecord 关系,因为在 Ruby 中除了 false 和 nil 之外的所有内容都是真实的。 || where(language_id: nil)
从未实际计算过。
在 Rails 中添加了对 .or
的支持 5. 在以前的版本中,最直接的解决方案是使用 Arel 或 SQL 字符串:
scope :non_arabic_languages, -> {
non_arabic_languages_ids = LOCALES[:non_arabic_languages].map { |h| h[:id] }
where(arel_table[:language_id].not_in(non_arabic_languages_ids ).or(arel_table[:language_id].eq(nil)))
}
我会留下标记评论(如@fixme),以便您在升级到 5.0 后修复此问题,或者考虑一个更好的解决方案,首先不涉及硬编码数据库 ID,例如使用 natural key.
我想获得除 [30, 54] 和 language_id 之外 language_id 的项目总数:无
LOCALES = {
non_arabic_languages: {
id: [30, 54]
}
}
scope :non_arabic_languages, -> { where.not(language_id: LOCALES[:non_arabic_languages][:id]) || where(language_id: nil) }
这个例子可以预见returns第一部分,所以我只得到非阿拉伯语的项目。 && 也有问题。我该如何组合它?我们将感谢您的建议!
您陷入了一个常见的陷阱,您将 Ruby 中的逻辑操作与通过 ActiveRecord 查询接口实际创建 SQL 混淆了。
使用 ||
将 return 第一个真实值:
where.not(language_id: LOCALES[:non_arabic_languages][:id]) || where(language_id: nil)
这是 return 由 where.not(language_id: LOCALES[:non_arabic_languages][:id])
编辑的 ActiveRecord 关系,因为在 Ruby 中除了 false 和 nil 之外的所有内容都是真实的。 || where(language_id: nil)
从未实际计算过。
在 Rails 中添加了对 .or
的支持 5. 在以前的版本中,最直接的解决方案是使用 Arel 或 SQL 字符串:
scope :non_arabic_languages, -> {
non_arabic_languages_ids = LOCALES[:non_arabic_languages].map { |h| h[:id] }
where(arel_table[:language_id].not_in(non_arabic_languages_ids ).or(arel_table[:language_id].eq(nil)))
}
我会留下标记评论(如@fixme),以便您在升级到 5.0 后修复此问题,或者考虑一个更好的解决方案,首先不涉及硬编码数据库 ID,例如使用 natural key.