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.