Kiểm tra xem bản ghi có tồn tại từ bộ điều khiển trong Rails không


91

Trong ứng dụng của tôi, Người dùng có thể tạo Doanh nghiệp. Khi họ kích hoạt indexhành động trong tôi, BusinessesControllertôi muốn kiểm tra xem Doanh nghiệp có liên quan đến current_user.id:

  • Nếu có: hiển thị doanh nghiệp.
  • Nếu không: chuyển hướng đến newhành động.

Tôi đã cố gắng sử dụng cái này:

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

Nhưng nó luôn trả về true ngay cả khi doanh nghiệp không tồn tại ...

Làm cách nào để kiểm tra xem bản ghi có tồn tại trong cơ sở dữ liệu của tôi không?


1
Việc sử dụng wheresẽ trả về một mảng trống nếu không có bản ghi nào. Và []không bằngnil
mind.blank

Điều gì về chỉ một unless Business.find_by_user_id(current_user.id)?
Hengjie

Câu trả lời:


230

Tại sao mã của bạn không hoạt động?

Các wheretrở về phương pháp một ActiveRecord :: Quan hệ đối tượng (đóng vai trò như một mảng chứa các kết quả của where), nó có thể để trống nhưng nó sẽ không bao giờ cónil .

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

Làm thế nào để kiểm tra nếu có ít nhất một bản ghi tồn tại?

Tùy chọn 1: Sử dụng.exists?

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

Tùy chọn 2: Sử dụng .present?(hoặc .blank?, ngược lại với .present?)

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

Tùy chọn 3: Phép gán biến trong câu lệnh if

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

Tùy chọn này có thể được coi là mùi mã đối với một số loại vải (Rubocop chẳng hạn).

Tùy chọn 3b: Chuyển nhượng biến

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

Bạn cũng có thể sử dụng .find_by_user_id(current_user.id)thay thế.where(...).first


Lựa chọn tốt nhất:

  • Nếu bạn không sử dụng Business(các) đối tượng: Tùy chọn 1
  • Nếu bạn cần sử dụng Business(các) đối tượng: Tùy chọn 3

Điều đó dường như không hoạt động. Nó tiếp tục vượt qua bài kiểm tra đó và tải html chỉ mục giống như với bài kiểm tra == nil (vì vậy tôi gặp lỗi: phương thức không xác định `name 'cho nil: NilClass).

Hãy thử với đầu tiên trước khi gọi quà
MrYoshiji

Tôi gặp vấn đề tương tự

Ồ, đó là lỗi của tôi, tôi đã nhầm lẫn, bạn cần kiểm tra vớiblank?
MrYoshiji

Cảm ơn đã làm việc! Tôi không nên nhận ra sai lầm đó. Bạn có thể cho tôi biết tại sao kiểm tra == nil không hoạt động không?

29

Trong trường hợp này, tôi muốn sử dụng exists?phương thức được cung cấp bởi ActiveRecord:

Business.exists? user_id: current_user.id

Là tồn tại? với HOẶC có thể?
Imran Ahmad

5

với 'tồn tại?':

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

với 'any?':

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

Nếu bạn sử dụng thứ gì đó với .where, hãy đảm bảo tránh rắc rối với phạm vi và sử dụng tốt hơn .unscoped

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

Tốt hơn hãy sử dụng Business.unscoped.where (: user_id => current_user.id) .pluck (: id) .any? để tránh tải quan hệ không cần thiết cho đối tượng bạn đang kiểm tra.
Juanin

1

ActiveRecord # nơi sẽ trả về một đối tượng ActiveRecord :: Relation (đối tượng này sẽ không bao giờ là nil). Hãy thử sử dụng .empty? về mối quan hệ để kiểm tra nếu nó sẽ trả về bất kỳ bản ghi nào.


1

Khi bạn gọi Business.where(:user_id => current_user.id)bạn sẽ nhận được một mảng. Mảng này có thể không có đối tượng hoặc một hoặc nhiều đối tượng trong đó, nhưng nó sẽ không rỗng. Vì vậy, kiểm tra == nil sẽ không bao giờ đúng.

Bạn có thể thử những cách sau:

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

Vì vậy, bạn kiểm tra số phần tử trong mảng và so sánh chúng với số không.

hoặc bạn có thể thử:

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

điều này sẽ trả về một hoặc không.


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

0

Tôi sẽ làm theo cách này nếu bạn cần một biến thể hiện của đối tượng để làm việc với:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.