В моем приложении пользователь может создать бизнес. Когда они запускают index
действие в моем, BusinessesController
я хочу проверить, связан ли бизнес с current_user.id
:
- Если да: покажите бизнес.
- Если нет: перенаправить к
new
действию.
Я пытался использовать это:
if Business.where(:user_id => current_user.id) == nil
# no business found
end
Но он всегда возвращает истину, даже если бизнеса не существует ...
Как я могу проверить, существует ли запись в моей базе данных?
ruby-on-rails
ruby-on-rails-3
activerecord
exists
MrYoshiji
источник
источник
where
вернет пустой массив, если нет записей. И[]
не равняетсяnil
unless Business.find_by_user_id(current_user.id)
?Ответы:
Почему твой код не работает?
В
where
методе возвращает ActiveRecord :: Отношение объект (действует как массив , который содержит результаты этогоwhere
), он может быть пустым , но он никогда не будетnil
.Business.where(id: -1) #=> returns an empty ActiveRecord::Relation ( similar to an array ) Business.where(id: -1).nil? # ( similar to == nil? ) #=> returns false Business.where(id: -1).empty? # test if the array is empty ( similar to .blank? ) #=> returns true
Как проверить, существует ли хотя бы одна запись?
Вариант 1: Использование
.exists?
if Business.exists?(user_id: current_user.id) # same as Business.where(user_id: current_user.id).exists? # ... else # ... end
Вариант 2. Использование
.present?
(или.blank?
противоположность.present?
)if Business.where(:user_id => current_user.id).present? # less efficiant than using .exists? (see generated SQL for .exists? vs .present?) else # ... end
Вариант 3: присвоение переменной в инструкции if
if business = Business.where(:user_id => current_user.id).first business.do_some_stuff else # do something else end
Некоторые линтеры (например, Rubocop) считают этот вариант запахом кода.
Вариант 3b: присвоение переменной
business = Business.where(user_id: current_user.id).first if business # ... else # ... end
Вы также можете использовать
.find_by_user_id(current_user.id)
вместо.where(...).first
Лучший вариант:
Business
объект (ы): Вариант 1Business
объект (ы): Вариант 3источник
blank?
В этом случае мне нравится использовать
exists?
метод, предоставляемый ActiveRecord:Business.exists? user_id: current_user.id
источник
с 'существует?':
Business.exists? user_id: current_user.id #=> 1 or nil
с любого?':
Business.where(:user_id => current_user.id).any? #=> true or false
Если вы используете что-то с .where, избегайте проблем с областями действия и лучше используйте .unscoped
Business.unscoped.where(:user_id => current_user.id).any?
источник
ActiveRecord # где вернет объект ActiveRecord :: Relation (который никогда не будет равен нулю). Попробуйте использовать .empty? по отношению к test, вернет ли он какие-то записи.
источник
При вызове
Business.where(:user_id => current_user.id)
вы получите массив. В этом массиве может не быть объектов или одного или нескольких объектов, но он не будет нулевым. Таким образом, проверка == nil никогда не будет истинной.Вы можете попробовать следующее:
if Business.where(:user_id => current_user.id).count == 0
Итак, вы проверяете количество элементов в массиве и сравниваете их с нулем.
или вы можете попробовать:
if Business.find_by_user_id(current_user.id).nil?
это вернет единицу или ноль.
источник
business = Business.where(:user_id => current_user.id).first if business.nil? # no business found else # business.ceo = "me" end
источник
Я бы сделал это так, если бы вам нужна была переменная экземпляра объекта для работы:
if @business = Business.where(:user_id => current_user.id).first #Do stuff else #Do stuff end
источник