kayıt yokken nil ile find ()


98

Şu anki rails programımda şöyle bir şey kullandığımda

 user = User.find(10)

ID = 10 olan bir kullanıcı olmadığında, şöyle bir istisnam olacak:

ActiveRecord::RecordNotFound: Couldn't find User with ID=10

İstisnayı yükseltmek yerine sıfır alabilir miyim, yani şöyle bir şey yaptığımda:

unless user = Challenge.find(10)
  puts "some error msg"         
end

Sadece kayıt olmadığında sıfır almak istiyorum ve başla / kurtarmayı kullanmak istemiyorum

Teşekkürler


Yanıtlar:


175

Evet, şunu yapın:

Challenge.find_by_id(10)

Raylar 4 ve 5 için:

Challenge.find_by(id: 10)

12
garip! Sıfırın .find_by_*döneceğini ve dönmeyeceğini asla tahmin .findedemezdim.
ddavison

Bu, raylar 4'te değişti, belirli bir özniteliğe göre bir öğeyi bulmanın yeni yolu için bu yanıta stackoverflow.com/a/26885027/1438478 bakın .
Fralcon

Rails 4.2 ile garip bir sorun buldum, burada bir hash'i 'x' Something.find_by(id: x)olarak ilettiğinizde, WHERE cümlesinin bir parçası olarak hash'in tüm öznitelik / değer çiftlerini içeren bir SQL ifadesi oluşturacaktır. Bana bir Rails böceği gibi görünüyor.
Tilo

Rails (3, 4 veya 5), find_by_...bir modelin sahip olduğu her özellik için dinamik bulucular oluşturur :id. Yani, Challenge.find_by_id(10)Rails sürümünden bağımsız olarak çalışmalıdır.
Arta

Aşağıda @MohamedIbrahim tarafından belirtildiği gibi şunları da yapabilirsiniz:Challenge.find(10) rescue nil
Hallgeir Wilhelmsen

31

Rails 4'te, find_by_idkabul edilen yanıtta kullanılanlar gibi dinamik bulucular kullanımdan kaldırıldı.

İlerlerken, yeni sözdizimini kullanmalısınız:

Challenge.find_by id: 10

4
Benim gibi başka birinin kafasının karışması durumunda: bunu Challenge.find_by(id: 10)yazmanın diğer yolu
Devin Howard

14

bunu biraz hile yapabilirsiniz, sadece ActiveRecord Sorgu Arayüzünü kullanın.

bu bir İstisna oluşturmak yerine sıfır döndürür

  User.where(:id => 10).first

Bunu kullanmanın bir nedeni find_by_id, Raylar 3'ten 4'e kadar taşınabilir olmasıdır. Raylarda 4, bu find_by(:id => 10).
Gene

5

Neden istisnayı yakalamıyorsun? Vakanız tam olarak hangi istisnaların yapıldığı gibi görünüyor:

begin
  user = User.find(10)
rescue ActiveRecord::RecordNotFound
  puts "some error msg"
end

Kurtarma bloğundaki hatayı düzeltmek istiyorsanız (örneğin, bir yer tutucu kullanıcı (boş şablon) ayarlayarak), bu bloğun altındaki kodunuzla devam edebilirsiniz. Aksi takdirde, "mutlu durum" için tüm kodunuzu "başla" ve "kurtarma" arasındaki bloğa koyabilirsiniz.


Btw: begin…endBir denetleyici yöntemi gibi bir bloğunuz zaten varsa , bloğa bile ihtiyacınız yoktur . Bu durumda ihtiyacınız olan tek ekstra hat rescuehattır. nilBir ififadeyle kontrol etmekten çok daha zarif ve kullanımı daha kolay .
morgler


4

Firavun faresi ile mücadele edenler için , hem findve hem de find_byyöntemlerin istisna yaratacağı ortaya çıktı - raylı versiyonunuz ne olursa olsun!

False olarak ayarlanabilen bir seçenek vardır (yani, yükseltmek_not_found_error ), ancak falseyfind yöntemi istisna oluşturmaz.

Bu nedenle, mongoid kullanıcıları için çözüm iğrenç bir koddur:

User.where(id: 'your_id').first # argghhh

Mohamed-ibrahim'in kurtarma sıfır çözümü hakkında ne düşünüyorsunuz? .where(email: params[:email]).firstBenden daha zarif görünüyor .
Wylliam Judd

1
rescueYazım hataları gibi sorunları gizleyebileceği için bu sözdizimini kullanmamayı tercih ederim
Cristiano Mendonça

@ Morgler'in çözümünü kullanarak yaralandım.
Wylliam Judd

2

kadar basit:

user = User.find(10) rescue nil

1
Hangi hatanın kurtarılmasının beklendiği konusunda daha net olmayı tercih ederim, bu durumda ActiveRecord :: RecordNotFound. @Morgler tarafından bu yanıta işaret edildiği gibi
luizrogeriocn

2
Şahsen bunu en iyi cevap olarak görüyorum. Kullanıcı şu konumda bulunmazsa ne yapacağımı söylüyorum zaten if user...else
koduma

0

Find_by'yi gerekli öznitelikle (sizin durumunuzda id) kullanabilirsiniz, bu, verilen kimlik bulunamazsa hata vermek yerine sıfır döndürür.

user = Challenge.find_by_id(id_value)

veya yeni biçimi kullanabilirsiniz:

user = Challenge.find_by id: id_value

Nerede de kullanabilirsiniz, ancak sıfır veya daha fazla kayıtla etkin bir kayıt ilişkisini döndürdüğünüzde, ilk önce yalnızca bir kayıt veya sıfır kayıt dönmesi durumunda sıfır döndürmek için kullanmanız gerektiğini bilmeniz gerekir.

user = Challenge.where(id: id_value).first
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.