У меня есть таблица с именем Codes в моем проекте.
irb(main):017:0> Code.new
=> #<Code id: nil, company_id: nil, name: nil, employee_uuid: nil, employee_email: nil, redeemed_at: nil, created_at: nil, updated_at: nil>
В моей базе данных у меня в общей сложности 97994 записей кода.
irb(main):018:0> Code.all.count
(127.7ms) SELECT COUNT(*) FROM "codes"
=> 97994
Итак, чего я не делаюпонять это следующее.До сих пор я проверял его с помощью атрибута name.
irb(main):019:0> Code.where(name: "").count
(135.0ms) SELECT COUNT(*) FROM "codes" WHERE "codes"."name" = ? [["name", ""]]
=> 0
irb(main):020:0> Code.where(name: " ").count
(18.3ms) SELECT COUNT(*) FROM "codes" WHERE "codes"."name" = ? [["name", " "]]
=> 0
, если при выполнении oposite Query он должен дать мне пропущенные объекты, в этом случае мой общий объем кодов.
irb(main):021:0> Code.where.not(name: "").count
(116.3ms) SELECT COUNT(*) FROM "codes" WHERE ("codes"."name" != ?) [["name", ""]]
=> 94652
irb(main):022:0> Code.where.not(name: " ").count
(19.9ms) SELECT COUNT(*) FROM "codes" WHERE ("codes"."name" != ?) [["name", " "]]
=> 94652
Но в результате я получаю 94652 вместо 97994 (из Code.all.count)
Это заставляет меня задуматься.Я проверил, какие левые коды:
irb(main):023:0> rest = Code.all - Code.where(name: "") - Code.where.not(name: "")
Code Load (1030.6ms) SELECT "codes".* FROM "codes"
Code Load (16.1ms) SELECT "codes".* FROM "codes" WHERE "codes"."name" = ? [["name", ""]]
Code Load (489.1ms) SELECT "codes".* FROM "codes" WHERE ("codes"."name" != ?) [["name", ""]]
... a huge array was returned
irb(main):024:0> rest.last
=> #<Code id: 86217, company_id: 307, name: nil, employee_uuid: "XXXXXXXXXXXXXX", employee_email: "XXXXX@EMAIL.COM", redeemed_at: "2018-07-09 12:30:29", created_at: "2018-12-11 13:07:57", updated_at: "2018-12-11 13:07:57">
Мне было интересно об этом, поэтому я проверил еще одну вещь:
irb(main):027:0> rest.last.name == ""
=> false
irb(main):028:0> rest.last.name != ""
=> true
, так что rest.last.name не ""(конечно, нет, зовут nil
)
но все же я получаю это
irb(main):025:0> Code.where(name: "").include? rest.last
Code Load (108.1ms) SELECT "codes".* FROM "codes" WHERE "codes"."name" = ? [["name", ""]]
=> false
irb(main):026:0> Code.where.not(name: "").include? rest.last
Code Load (365.9ms) SELECT "codes".* FROM "codes" WHERE ("codes"."name" != ?) [["name", ""]]
=> false
Я всегда думал, где что-то, и его отрицательный всегда будет составлять общую сумму, то есть когдачто-то случается, и когда этого не происходит, мы всегда отвечаем.A + !A = 1
Почему я это вижу?я не могу следить за этим.
Заранее спасибо за помощь.
Обновите вопрос, чтобы ответить на комментарии:
irb(main):002:0> Code.where(name: [nil, '']).count
(432.2ms) SELECT COUNT(*) FROM "codes" WHERE ("codes"."name" = '' OR "codes"."name" IS NULL)
=> 3342
и это число в точности равно
irb(main):003:0> Code.all.count - Code.where.not(name: "").count
(315.2ms) SELECT COUNT(*) FROM "codes"
(332.5ms) SELECT COUNT(*) FROM "codes" WHERE ("codes"."name" != ?) [["name", ""]]
=> 3342
Хорошо, пока я понимаю, что SQL не может сравниваться с Nil или нет, когда я проверяю, является ли строка пустой.Это означает, что мне нужно либо выполнить запрос с массивом [nil, '']
, либо подумать иначе ...