【问题标题】:ActiveRecord OR query behavior when first argument is nil第一个参数为 nil 时的 ActiveRecord OR 查询行为
【发布时间】:2015-11-18 07:29:01
【问题描述】:

foo=nilbar=43 的记录。为什么以下查询与该记录不匹配。它不应该只检查foo,因为它与给定值匹配(即nil)吗?

myrecords.where("foo = ? OR bar = ?", nil, 42).first

【问题讨论】:

    标签: sql ruby-on-rails ruby ruby-on-rails-3 rails-activerecord


    【解决方案1】:

    嘿,你可以尝试这种方式 null 值在 mysql 中不进行比较以获取更多NULL 值的信息参考 Working with NULL Values

    myrecords.where("foo is null OR bar = ?", 42).first
    

    如果您不知道对象的值是nullnot null使用mysql的NULL-safe equal to operator 作为:

     myrecords.where("foo <=> ? OR bar = ?", nil, 42).first
    

    【讨论】:

    • 如果我知道该值为空,则此方法有效。但是如果代码是myrecords.where("foo = ? OR bar = ?", some_obj_could_be_nil, 42).first。有没有更好的办法?
    • 谢谢!我希望 Rails 中有一个独立于数据库的解决方案
    • @balki 在更高版本的rails中你可以在rails活动记录查询中放置OR条件或Arel查询你可以放置OR然后你可以直接创建活动记录查询。那么它们不是依赖于数据库的部分。
    【解决方案2】:

    这应该可行:

    myrecords.where("foo = ? OR bar = ?", NULL, 42).first
    

    【讨论】:

    • where(foo: nil, bar: 42) 这个地方是OR 子句吗?我认为它将AND 放在mysql 查询中。并且 OP 需要OR
    • 什么是NULL?某个地方定义的常数?问题是mysql特定的。其他地方的行为可能会有所不同?
    • 没错,这就是为什么我有第二个解决方案(我删除了它,因为它创建了 AND 查询)。只需编写一个单元测试以确认它在您当前的设置中有效。或者使用能够执行 OR 查询的 gem。我认为 MetaWhere 是这样做的。
    • 附言。看起来 Rails 5 将支持使用 .or 方法来链接多个 .where,但目前这可能对您没有帮助。
    猜你喜欢
    • 2011-04-08
    • 2016-12-30
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多