W mojej aplikacji Użytkownik może założyć Firmę. Kiedy wyzwalają index
akcję w moim BusinessesController
Chcę sprawdzić, czy Firma jest związana z current_user.id
:
- Jeśli tak: wyświetl firmę.
- Jeśli nie: przekieruj do
new
akcji.
Próbowałem tego użyć:
if Business.where(:user_id => current_user.id) == nil
# no business found
end
Ale zawsze zwraca prawdę, nawet jeśli firma nie istnieje ...
Jak mogę sprawdzić, czy rekord istnieje w mojej bazie danych?
ruby-on-rails
ruby-on-rails-3
activerecord
exists
MrYoshiji
źródło
źródło
where
zwróci pustą tablicę, jeśli nie ma żadnych rekordów. I[]
nie równa sięnil
unless Business.find_by_user_id(current_user.id)
?Odpowiedzi:
Dlaczego twój kod nie działa?
Że
where
metoda zwraca ActiveRecord :: Relacja obiektu (działa jak tablica, która zawiera wyniki Spośródwhere
), to może być pusty, ale to nigdy nie będzienil
.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
Jak sprawdzić, czy istnieje co najmniej jeden rekord?
Opcja 1: używanie
.exists?
if Business.exists?(user_id: current_user.id) # same as Business.where(user_id: current_user.id).exists? # ... else # ... end
Opcja 2: używanie
.present?
(lub.blank?
przeciwieństwo.present?
)if Business.where(:user_id => current_user.id).present? # less efficiant than using .exists? (see generated SQL for .exists? vs .present?) else # ... end
Opcja 3: przypisanie zmiennej w instrukcji if
if business = Business.where(:user_id => current_user.id).first business.do_some_stuff else # do something else end
Tę opcję można uznać za zapach kodu przez niektóre lintery (na przykład Rubocop).
Opcja 3b: przypisanie zmiennych
business = Business.where(user_id: current_user.id).first if business # ... else # ... end
Możesz także użyć
.find_by_user_id(current_user.id)
zamiast.where(...).first
Najlepsza opcja:
Business
obiektów: opcja 1Business
obiektów: opcja 3źródło
blank?
W tym przypadku lubię skorzystać z
exists?
metody udostępnionej przez ActiveRecord:Business.exists? user_id: current_user.id
źródło
z „istnieje?”:
Business.exists? user_id: current_user.id #=> 1 or nil
z jakimkolwiek?':
Business.where(:user_id => current_user.id).any? #=> true or false
Jeśli używasz czegoś z .where, unikaj problemów z celownikami i lepiej używaj .unscoped
Business.unscoped.where(:user_id => current_user.id).any?
źródło
ActiveRecord # gdzie zwróci obiekt ActiveRecord :: Relation (który nigdy nie będzie zerowy). Spróbuj użyć .empty? w związku z testem, czy zwróci jakiekolwiek rekordy.
źródło
Kiedy zadzwonisz
Business.where(:user_id => current_user.id)
, otrzymasz tablicę. Ta tablica może nie zawierać żadnych obiektów lub jednego lub wielu obiektów, ale nie będzie miała wartości NULL. Tak więc check == nil nigdy nie będzie prawdziwe.Możesz spróbować następujących rzeczy:
if Business.where(:user_id => current_user.id).count == 0
Więc sprawdzasz liczbę elementów w tablicy i porównujesz je do zera.
lub możesz spróbować:
if Business.find_by_user_id(current_user.id).nil?
to zwróci jeden lub zero.
źródło
business = Business.where(:user_id => current_user.id).first if business.nil? # no business found else # business.ceo = "me" end
źródło
Zrobiłbym to w ten sposób, gdybyś potrzebował zmiennej instancji obiektu do pracy:
if @business = Business.where(:user_id => current_user.id).first #Do stuff else #Do stuff end
źródło