Перевірте, чи існує запис від контролера в Rails


91

У моєму додатку Користувач може створити бізнес. Коли вони ініціюють indexдію в моєму, BusinessesControllerя хочу перевірити, чи пов’язаний бізнес із current_user.id:

  • Якщо так: покажіть бізнес.
  • Якщо ні: перенаправити на newдію.

Я намагався використати це:

if Business.where(:user_id => current_user.id) == nil
  # no business found
end

Але це завжди повертається, навіть коли бізнесу не існує ...

Як я можу перевірити, чи існує запис у моїй базі даних?


1
Використання whereповерне порожній масив, якщо немає записів. І []не рівнеnil
mind. Пусто

А як щодо просто unless Business.find_by_user_id(current_user.id)?
Hengjie

Відповіді:


229

Чому ваш код не працює?

У 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об'єкт (и): Варіант 1
  • Якщо вам потрібно використовувати Businessоб’єкт (и): Варіант 3

Здається, це не спрацювало. Він продовжує проходити цей тест і завантажувати індекс html, як при тесті == nil (тому я отримую помилку: undefined method `name 'для nil: NilClass).

Спробуйте спершу, перш ніж зателефонувати справжньому
MrYoshiji

У мене така сама проблема

О, це моя вина, я blank?
заплутався

Дякую, що спрацювало! Я не повинен був помітити цю помилку. Не могли б ви сказати мені, чому перевірка == нуль не спрацювала?

29

У цьому випадку я люблю використовувати exists?метод, наданий ActiveRecord:

Business.exists? user_id: current_user.id

Є існує? з АБО можливо?
Імран Ахмад,

5

з "існує?":

Business.exists? user_id: current_user.id #=> 1 or nil

з "будь-яким?":

Business.where(:user_id => current_user.id).any? #=> true or false

Якщо ви використовуєте щось із .where, обов’язково уникайте проблем із сферами застосування та краще використовуйте .nscoped

Business.unscoped.where(:user_id => current_user.id).any?

Краще використовувати Business.unscoped.where (: user_id => current_user.id) .pluck (: id) .any? щоб уникнути непотрібного навантаження відносин для об’єкта, який ви перевіряєте.
Хуанін

1

ActiveRecord # де поверне об'єкт ActiveRecord :: Relation (який ніколи не буде нульовим). Спробуйте використовувати .empty? щодо відношення до тесту, якщо він поверне якісь записи.


1

Коли ви телефонуєте, 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?

це поверне один або нуль.



0

Я б зробив це таким чином, якщо вам потрібна змінна екземпляра об’єкта для роботи:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.