Rails where condition with nil value

前端 未结 5 887
我在风中等你
我在风中等你 2021-02-05 03:16

I found out that using where with symbol :my_id => nil and using old school one with ? is different. Could anyone explain me why?

MyTable.where(\"my_id = ? \", n         


        
相关标签:
5条回答
  • 2021-02-05 03:46

    For DB for NULL the syntax should be

    my_id IS NULL
    

    So you can give it as:

    MyTable.where("my_id is NULL ").first
    
    0 讨论(0)
  • 2021-02-05 03:48

    I suppose it's so called "rails magic" you can pass ranges

    Client.where(:created_at => (Time.now.midnight - 1.day)..Time.now.midnight)
    

    becomes

    SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' 
                                                        AND '2008-12-22 00:00:00')
    

    or if you pass a subset

    Client.where(:orders_count => [1,3,5])
    

    rails will do

    SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
    

    more

    0 讨论(0)
  • 2021-02-05 03:52

    In rails 4 you can specify the value as null using the new hash syntax.

    MyTable.where(my_id: nil).first
    
    0 讨论(0)
  • 2021-02-05 03:57

    The correct SQL syntax is my_id IS NULL, so if you change your first snippet to the following it will work:

    MyTable.where("my_id IS ?", nil).first
    

    Both syntaxes are perfectly fine. It's up to your own preference. However, if it's a parameter and you don't know whether it will be nil or not, you'd better use:

    MyTable.where(:my_id => parameter).first
    
    0 讨论(0)
  • 2021-02-05 03:58

    For any relational database the predicate (my_id = NULL ) is always false, because NULL never equals anything - not even NULL.

    A more complete explanation is here https://dba.stackexchange.com/questions/166579/why-is-null-ignored-in-query-results/166586#166586.

    ActiveRecord will cope with this very well, even when null is included in an array.

    irb(main):029:0> Book.where(id: 1).to_sql
    => "SELECT ... WHERE \"books\".\"id\" = 1"
    irb(main):030:0> Book.where(id: nil).to_sql
    => "SELECT ... WHERE \"books\".\"id\" IS NULL"
    irb(main):031:0> Book.where(id: [1, nil]).to_sql
    => "SELECT ... WHERE (\"books\".\"id\" = 1 OR \"books\".\"id\" IS NULL)"
    
    0 讨论(0)
提交回复
热议问题