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?


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

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

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

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?

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.


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.


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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.