Periksa apakah ada record dari controller di Rails

91

Di aplikasi saya, Pengguna bisa membuat Bisnis. Ketika mereka memicu indextindakan di saya, BusinessesControllersaya ingin memeriksa apakah Bisnis terkait dengan current_user.id:

  • Jika ya: tampilkan bisnisnya.
  • Jika tidak: alihkan ke newtindakan.

Saya mencoba menggunakan ini:

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

Tapi itu selalu mengembalikan true bahkan ketika bisnis tidak ada ...

Bagaimana saya bisa menguji jika catatan ada di database saya?

MrYoshiji
sumber
1
Menggunakan whereakan mengembalikan larik kosong jika tidak ada catatan. Dan []tidak samanil
mind.blank
Bagaimana dengan hanya a unless Business.find_by_user_id(current_user.id)?
Hengjie
kemungkinan duplikat Memeriksa apakah ActiveRecord menemukan mengembalikan hasil
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

231

Mengapa kode Anda tidak berfungsi?

The wherekembali metode sebuah ActiveRecord :: Relation objek (bertindak seperti sebuah array yang berisi hasil where), itu bisa kosong tapi itu tidak akan pernahnil .

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

Bagaimana cara menguji jika setidaknya ada satu catatan?

Opsi 1: Menggunakan.exists?

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

Opsi 2: Menggunakan .present?(atau .blank?, kebalikan dari .present?)

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

Opsi 3: Penugasan variabel dalam pernyataan if

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

Opsi ini dapat dianggap sebagai code bau oleh beberapa linter (misalnya Rubocop).

Opsi 3b: Penugasan variabel

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

Anda juga dapat menggunakan .find_by_user_id(current_user.id)bukannya.where(...).first


Pilihan terbaik:

  • Jika Anda tidak menggunakan Businessobjek: Opsi 1
  • Jika Anda perlu menggunakan Businessobjek: Opsi 3
MrYoshiji
sumber
Sepertinya itu tidak berhasil. Itu terus melewati tes itu dan memuat indeks html seperti dengan tes == nil (jadi saya mendapatkan kesalahan: metode `nama 'yang tidak ditentukan untuk nil: NilClass).
Coba dulu sebelum menelepon sekarang
MrYoshiji
Saya mendapatkan masalah yang sama
Oh, itu salah saya, saya bingung, Anda perlu menguji denganblank?
MrYoshiji
Terima kasih itu berhasil! Saya seharusnya tidak memperhatikan kesalahan itu. Bisakah Anda memberi tahu saya mengapa pemeriksaan == nil tidak berhasil?
29

Dalam hal ini saya suka menggunakan exists?metode yang disediakan oleh ActiveRecord:

Business.exists? user_id: current_user.id
Hamed
sumber
Apakah ada? dengan ATAU mungkin?
Imran Ahmad
5

dengan 'ada?':

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

dengan 'apa saja?':

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

Jika Anda menggunakan sesuatu dengan .where, pastikan untuk menghindari masalah dengan cakupan dan lebih baik menggunakan .unscoped

Business.unscoped.where(:user_id => current_user.id).any?
pengguna2427993
sumber
Lebih baik gunakan Business.unscoped.where (: user_id => current_user.id) .pluck (: id) .any? untuk menghindari pemuatan relasi yang tidak perlu untuk objek yang Anda periksa.
Juanin
1

ActiveRecord # where akan mengembalikan objek ActiveRecord :: Relation (yang tidak akan pernah nihil). Coba gunakan .empty? pada hubungan untuk menguji apakah itu akan mengembalikan catatan apa pun.

Puhlze
sumber
1

Saat Anda menelepon, Business.where(:user_id => current_user.id)Anda akan mendapatkan array. Array ini mungkin tidak memiliki objek atau satu atau banyak objek di dalamnya, tetapi tidak akan null. Jadi cek == nil tidak akan pernah benar.

Anda dapat mencoba yang berikut ini:

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

Jadi Anda memeriksa jumlah elemen dalam larik dan membandingkannya dengan nol.

atau Anda dapat mencoba:

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

ini akan mengembalikan satu atau nol.

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

Saya akan melakukannya dengan cara ini jika Anda membutuhkan variabel contoh dari objek untuk bekerja dengan:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
pengguna3633260
sumber