Ric*_*ich 3 ruby activerecord ruby-on-rails
I'm struggling to wrap my mind around an ActiveRecord query.
I'm trying to search my database for GolfRetailer objects with ID's 1..100, that have something (not nil) in their :website field, and that don't have true in their duplicate_domain field.
Here's the query I expected to work:
GolfRetailer.where.not(website: nil, duplicate_domain: true).where(id: 1..100)
I also tried this variant of essentially the same query: GolfRetailer.where.not(website: nil).where(id: 1..100, duplicate_domain: !true)
But both return an empty array, despite there definitely being records that meet those requirements.
When I run GolfRetailer.where.not(website: nil).where(id: 1..100) I get an array, and when I run GolfRetailer.where.not(website: nil, duplicate_domain: nil).where(id: 1..100) I also get an array, but with all records that do have the true duplicate_domain flag, which isn't what I'm looking for.
I'd rather not search for records that have duplicate_domain: nil as that's not always correct (I may not have processed their domain yet).
For clarity, here is the Schema for the Model.
create_table "golf_retailers", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "place_id"
t.string "website"
t.string "formatted_address"
t.string "google_places_name"
t.string "email"
t.boolean "duplicate_domain"
t.index ["duplicate_domain"], name: "index_golf_retailers_on_duplicate_domain"
end
Run Code Online (Sandbox Code Playgroud)
What am I missing to make this query work?
发生这种情况是因为在SQL中执行a时!= TRUE,NULL结果中将不包含任何值。这是因为该NULL值表示一个未知值,所以DB不知道如何对未知值执行任何比较操作,因此将它们排除在外。
解决此问题的一种方法是使用IS DISTINCT FROM:
GolfRetailer
.where(id: 1..100)
.where.not(website: nil)
.where("duplicate_domain IS DISTINCT FROM ?", true)
Run Code Online (Sandbox Code Playgroud)
正如其他人提到的那样,您还应该问自己,如果a确实GolfRetailer有一个,是否真的不为您所知duplicate_domain。
如果,所有GolfRetailer符合S duplicate_domain的NULL实际上意味着他们没有一个(false)比你应该考虑防止NULL值该列完全。
您可以通过在change_column数据库迁移的列上添加NOT NULL约束来实现。
为了添加NOT NULL约束,您首先需要确保该列中的所有数据都具有非null值。
def change
GolfRetailer.in_batches.update_all(duplicate_domain: false)
change_column_null :golf_retailers, :duplicate_domain
end
Run Code Online (Sandbox Code Playgroud)
如果您的应用程序处于负载状态,则还应注意此类迁移可能具有的潜在性能-特别是如果您添加具有默认值的NOT NULL约束。
考虑使用诸如Strong Migrations gem之类的工具来帮助查找可能导致生产前停机的数据库迁移。
| 归档时间: |
|
| 查看次数: |
69 次 |
| 最近记录: |