Найти записи, в которых присутствует атрибут
У меня есть модель User
с атрибутами username
, email
и name
.
username
и email
требуются при регистрации, но не name
.
Каким будет запрос, чтобы найти всех пользователей, которые заполнили name
(т.е. это не нуль)?
Запрос должен быть не менее совместимым с Rails 3.2 и 4.0.
Я думаю что-то в строках:
User.where(name: present?)
Ответы
Ответ 1
присутствует
present?
по существу not nil and not empty?
:
class Object
def present?
!blank?
end
def blank?
respond_to?(:empty?) ? !!empty? : !self
end
end
Состояние ActiveRecord
В Rails 4 не могут быть выполнены условия без необработанного кода sql.
# Both lines lead to the same result:
User.where.not(name: [nil, ""])
User.where.not(name: nil).where.not(name: "")
Поскольку нет сырого кода sql, вам не нужно беспокоиться о том, работают ли они с каждым адаптером базы данных. На самом деле, это отлично работает как для mysql, так и для postgres.
to_sql
Вы можете увидеть, как они преобразуются в sql-запросы, если вы добавляете .to_sql
, например, в консоль rails.
# rails console
User.where.not(name: [nil, ""]).to_sql
# => "SELECT \"users\".* FROM \"users\" WHERE (NOT ((\"users\".\"name\" = '' OR \"users\".\"name\" IS NULL)))"
User.where.not(name: nil).where.not(name: "").to_sql
# => "SELECT \"users\".* FROM \"users\" WHERE (\"users\".\"name\" IS NOT NULL) AND (\"users\".\"name\" != '')"
Дополнительная литература
Ответ 2
Пустое значение в базе данных получает специальное значение NULL
. При тестировании, установленном, используется специальный компаратор IS NULL
или IS NOT NULL
.
Тогда все еще остается возможность заполнения пустой строки, поэтому полный тест будет
@users = User.where("name is NOT NULL and name != ''")
Ответ 3
НЕ SQL-запросы могут быть построены с помощью where.not
@users = User.where.not(name: nil)
Ответ 4
Попробуйте следующее:
User.where("name IS NOT NULL AND name != ?", "")
Я отредактировал свой ответ в соответствии с комментариями @nathavanda, который, по моему мнению, должен быть принят.
Ответ 5
Rails 3 сортировать после условия .where, используя NOT NULL
@users = User.where('name IS NOT NULL')