Active Record, где не логическое значение: true

Я изо всех сил пытаюсь понять запрос ActiveRecord.

Я пытаюсь найти в своей базе данных объекты GolfRetailer с идентификаторами 1..100, у которых есть что-то (не nil) в их поле :website, и у которых нет true в их поле duplicate_domain.

Вот запрос, который я ожидал сработать:

GolfRetailer.where.not(website: nil, duplicate_domain: true).where(id: 1..100)

Я также пробовал этот вариант по сути того же запроса: GolfRetailer.where.not(website: nil).where(id: 1..100, duplicate_domain: !true)

Но оба возвращают пустой массив, несмотря на то, что определенно есть записи, соответствующие этим требованиям.

Когда я запускаю GolfRetailer.where.not(website: nil).where(id: 1..100), я получаю массив, а когда я запускаю GolfRetailer.where.not(website: nil, duplicate_domain: nil).where(id: 1..100), я также получаю массив, но со всеми записями, которые делать имеют истинный флаг повторяющегося_домена, а это не то, что я ищу.

Я бы предпочел не искать записи с duplicate_domain: nil, так как это не всегда правильно (возможно, я еще не обработал их домен).

Для ясности, вот схема для модели.

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

Чего мне не хватает, чтобы этот запрос работал?

Я бы предложил значение по умолчанию false для атрибута duplicate_domain. Вы можете сделать это задним числом, добавив GolfRetailer.where(duplicate_domain: nil).update_all(duplicate_domain: false). Как только единственные параметры будут истинными или ложными, первый запрос должен работать нормально. Проблема в том, что сейчас это 3 состояния (истина, ложь или ноль), а не (истина) не равно NULL в SQL.

engineersmnky 26.03.2019 16:46

Я настоятельно рекомендую переключиться на t.boolean "duplicate_domain", null: false для столбца, null в логическом столбце редко то, что вам нужно. Кроме того, индексация логического столбца (или любого столбца с низкой кардинальностью), вероятно, не поможет, проверьте выходные данные EXPLAIN в ваших запросах, чтобы увидеть, используется ли когда-либо этот индекс.

mu is too short 26.03.2019 18:07

Эти комментарии помогли мне лучше понять хороший дизайн. Спасибо, что нашли время, чтобы объяснить это.

Rich 27.03.2019 12:49
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
3
727
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это происходит потому, что в SQL, когда вы делаете != TRUE, любые значения NULL не будут включены в результат. Это связано с тем, что значение NULL представляет собой неизвестное значение, поэтому БД не знает, как выполнить какие-либо операции сравнения с неизвестным значением, и поэтому они исключены.

Один из способов обойти это — использовать IS DISTINCT FROM:

GolfRetailer
  .where(id: 1..100)
  .where.not(website: nil)
  .where("duplicate_domain IS DISTINCT FROM ?", true)

Как уже упоминали другие, вы также должны спросить себя, действительно ли это так, что вам никогда не известно, есть ли у GolfRetailerduplicate_domain.

Если все GolfRetailer с duplicate_domain из NULL на самом деле означают, что у них нет ни одного (false), то вам следует рассмотреть возможность полного предотвращения значения NULL для этого столбца.

Вы можете сделать это, добавив ограничение NOT NULL для столбца с change_column миграция базы данных.

Чтобы добавить ограничение NOT NULL, вам сначала нужно убедиться, что все данные в столбце имеют ненулевые значения.

def change
  GolfRetailer.in_batches.update_all(duplicate_domain: false)

  change_column_null :golf_retailers, :duplicate_domain
end

Если ваше приложение находится под нагрузкой, вы также должны быть осторожны с потенциальной производительностью, которую может иметь любая миграция, подобная этой, особенно если вы добавите ограничение NOT NULL со значением по умолчанию.

Рассмотрите возможность использования чего-то вроде драгоценного камня Сильные миграции, чтобы помочь найти миграции БД, которые могут вызвать простои перед производством.

Другие вопросы по теме

Похожие вопросы

Ошибка времени выполнения приложения rails сообщает о другой версии драгоценного камня пакета действий, отличной от установки установки пакета
Elastic Beanstalk: не удается найти сборщик драгоценных камней (>= 0.a) с исполняемым пакетом (Gem::GemNotFoundException)
Любопытство. Почему документация по Django REST Framework должна создаваться с помощью RoR?
Как отобразить виртуальный атрибут в форме редактирования Rails Admin
Как запросить несколько связанных таблиц в Rails
Возникает ошибка при попытке получить значки входа/выхода и учетной записи в Rails, как я могу это исправить?
Отсутствует поле данных ответа на запрос Ajax GET
Как добавить процент в ограничение маршрута ruby ​​on rails
В Rails 5.2, используя гем Carrierwave, как я могу использовать гем по умолчанию, когда файл больше не существует на диске?
Получить все вакансии, дата которых старше сегодняшней даты, и отфильтровать по пользователю и количеству отзывов на вакансию