Rails의 컨트롤러에서 레코드가 있는지 확인


92

내 앱에서 사용자는 비즈니스를 만들 수 있습니다. 그들이 index내 에서 작업 을 트리거하면 BusinessesController비즈니스가 다음과 관련되어 있는지 확인하고 싶습니다 current_user.id.

  • 그렇다면 : 업체를 표시하십시오.
  • 그렇지 않은 경우 : new작업으로 리디렉션합니다 .

나는 이것을 사용하려고했다 :

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

그러나 그것은 사업이 존재하지 않더라도 항상 사실을 반환합니다.

내 데이터베이스에 레코드가 있는지 어떻게 테스트 할 수 있습니까?


1
을 사용 where하면 레코드가없는 경우 빈 배열이 반환됩니다. 그리고 []같지 않습니다nil
mind.blank

그냥 unless Business.find_by_user_id(current_user.id)어때?
Hengjie

답변:


233

코드가 작동하지 않는 이유는 무엇입니까?

where메서드는 ActiveRecord :: Relation 객체를 반환 합니다 (의 결과를 포함하는 배열처럼 작동 함 where). 비어있을 수 있지만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

하나 이상의 레코드가 있는지 테스트하는 방법은 무엇입니까?

옵션 1 : 사용.exists?

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

옵션 2 : 사용 .present?(또는 .blank?의 반대 .present?)

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

옵션 3 : if 문의 변수 할당

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

이 옵션은 일부 린터 (예 : Rubocop)에 의해 코드 냄새로 간주 될 수 있습니다.

옵션 3b : 변수 할당

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

.find_by_user_id(current_user.id)대신 사용할 수도 있습니다..where(...).first


최상의 옵션 :

  • Business개체를 사용하지 않는 경우 : 옵션 1
  • Business개체 를 사용해야하는 경우 : 옵션 3

작동하지 않는 것 같습니다. 이 테스트를 계속 통과하고 == nil 테스트와 같이 인덱스 html을로드합니다 (그래서 오류가 발생합니다 : nil : NilClass에 대해 정의되지 않은 메소드`name ').

선물을 부르기 전에 먼저 시도하십시오
MrYoshiji

같은 문제가 발생합니다

오 그게 내 잘못이야, 당신은 테스트가 필요합니다blank?
MrYoshiji

감사합니다! 나는 그 실수를 알아 차리지 못 했어야했다. == nil 검사가 작동하지 않는 이유를 말씀해 주시겠습니까?

29

이 경우 exists?ActiveRecord에서 제공 하는 방법 을 사용하고 싶습니다 .

Business.exists? user_id: current_user.id

존재합니까? OR 가능?
Imran Ahmad

5

'존재합니까?':

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

'any?'와 함께 :

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

.where와 함께 무언가를 사용하는 경우 범위 문제를 피하고 .unscoped를 더 잘 사용 하십시오.

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

Business.unscoped.where (: user_id => current_user.id) .pluck (: id) .any를 더 잘 사용합니까? 검사중인 객체에 대해 불필요한 관계로드를 방지합니다.
Juanin dec.

1

ActiveRecord # where는 ActiveRecord :: Relation 개체를 반환합니다 (이는 절대 nil이 아님). .empty를 사용해 보시겠습니까? 레코드를 반환하는지 테스트 할 관계에 있습니다.


1

전화 Business.where(:user_id => current_user.id)하면 배열을 받게됩니다. 이 배열에는 개체가 없거나 하나 또는 여러 개체가있을 수 있지만 null은 아닙니다. 따라서 check == nil은 결코 사실이 아닙니다.

다음을 시도 할 수 있습니다.

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

따라서 배열의 요소 수를 확인하고 0과 비교합니다.

또는 시도해 볼 수 있습니다.

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

이것은 하나 또는 nil을 반환합니다.


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

0

작업 할 개체의 인스턴스 변수가 필요한 경우이 방법을 사용합니다.

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.