Rails'te denetleyiciden kayıt olup olmadığını kontrol edin


91

Uygulamamda bir Kullanıcı bir İşletme oluşturabilir. Bende indexeylemi tetiklediklerinde, BusinessesControllerbir İşletmenin aşağıdakilerle ilişkili olup olmadığını kontrol etmek istiyorum current_user.id:

  • Evet ise: işletmeyi gösterin.
  • Hayır ise: neweyleme yönlendirin .

Bunu kullanmaya çalışıyordum:

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

Ama iş olmasa bile her zaman doğru olur ...

Veritabanımda bir kayıt olup olmadığını nasıl test edebilirim?


1
Kayıt whereyoksa boş bir dizi döndürür. Ve []eşit değilnil
mind.blank

Ya sadece bir unless Business.find_by_user_id(current_user.id)?
Hengjie

Yanıtlar:


231

Kodunuz neden çalışmıyor?

whereBir yöntem, döner ActiveRecord :: ilişki nesnesi (sonuçlarını içeren bir dizi gibi davranan where), boş olabilir ama aslanil .

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

En az bir kayıt olup olmadığı nasıl test edilir?

Seçenek 1: Kullanma.exists?

if Business.exists?(user_id: current_user.id)
  # same as Business.where(user_id: current_user.id).exists?
  # ...
else
  # ...
end

2. Seçenek: Kullanmak .present?(veya .blank?tersi .present?)

if Business.where(:user_id => current_user.id).present?
  # less efficiant than using .exists? (see generated SQL for .exists? vs .present?)
else
  # ...
end

Seçenek 3: if ifadesindeki değişken atama

if business = Business.where(:user_id => current_user.id).first
  business.do_some_stuff
else
  # do something else
end

Bu seçenek bazı linterler tarafından bir kod kokusu olarak düşünülebilir (örneğin Rubocop).

Seçenek 3b: Değişken atama

business = Business.where(user_id: current_user.id).first
if business
  # ...
else
  # ...
end

Bunun .find_by_user_id(current_user.id)yerine de kullanabilirsiniz.where(...).first


En iyi seçenek:

  • BusinessNesneleri kullanmıyorsanız : 1. Seçenek
  • BusinessNesneleri kullanmanız gerekirse : 3. Seçenek

Bu işe yaramadı. == nil testinde olduğu gibi bu testi geçmeye ve html indeksini yüklemeye devam ediyor (bu yüzden bir hata alıyorum: nil: NilClass için tanımsız yöntem adı ').


Aynı sorunu

Oh, bu benim hatam, blank?
kafam karıştı

Çalıştığı için teşekkürler! Bu hatayı fark etmemeliydim. == nil kontrolünün neden işe yaramadığını bana söyleyebilir misiniz?

29

Bu durumda exists?ActiveRecord tarafından sağlanan yöntemi kullanmayı seviyorum :

Business.exists? user_id: current_user.id

Var mı? OR ile mümkün mü?
Imran Ahmad

5

'var mı?' ile:

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

"herhangi biri" ile:

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

.Where ile bir şey kullanıyorsanız, kapsamlarla ilgili sorunlardan kaçındığınızdan ve .unscoped'i daha iyi kullandığınızdan emin olun

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

Business.unscoped.where (: user_id => current_user.id) .pluck (: id) .any? kontrol ettiğiniz nesne için gereksiz ilişki yükünden kaçınmak için.
Juanin

1

ActiveRecord #, bir ActiveRecord :: Relation nesnesi (asla sıfır olmayacak) döndürür. .Empty kullanmayı deneyin? herhangi bir kayıt döndürüp döndürmeyeceğini test etmekle ilgili


1

Aradığınızda Business.where(:user_id => current_user.id)bir dizi alacaksınız. Bu Dizinin içinde hiçbir nesne veya bir veya birden fazla nesne olmayabilir, ancak boş olmayacaktır. Bu nedenle == nil kontrolü asla doğru olmayacaktır.

Aşağıdakileri deneyebilirsiniz:

if Business.where(:user_id => current_user.id).count == 0

Yani dizideki elemanların sayısını kontrol edip sıfırla karşılaştırırsınız.

veya deneyebilirsiniz:

if Business.find_by_user_id(current_user.id).nil?

bu bir veya sıfır döndürür.


1
business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end

0

Çalışmak için nesnenin bir örnek değişkenine ihtiyacınız olsaydı bunu şu şekilde yapardım:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.