私のアプリでは、ユーザーはビジネスを作成できます。 index
でBusinessesController
アクションをトリガーするとき、ビジネスがcurrent_user.id
に関連しているかどうかを確認したい:
new
アクションにリダイレクトします。私はこれを使用しようとしていました:
if Business.where(:user_id => current_user.id) == nil
# no business found
end
しかし、ビジネスが存在しない場合でも常にtrueを返します...
データベースにレコードが存在するかどうかをテストするにはどうすればよいですか?
コードが機能しないのはなぜですか?
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
オブジェクトを使用しない場合:オプション1Business
オブジェクトを使用する必要がある場合:オプション3この場合、ActiveRecordが提供するexists?
メソッドを使用します。
Business.exists? user_id: current_user.id
「存在しますか?」
Business.exists? user_id: current_user.id #=> 1 or nil
「何か?」
Business.where(:user_id => current_user.id).any? #=> true or false
。whereで何かを使用する場合は、スコープの問題を回避し、より適切に使用してください 。unscoped (
Business.unscoped.where(:user_id => current_user.id).any?
ActiveRecord#whereは、ActiveRecord :: Relationオブジェクトを返します(nilになることはありません)。 .emptyを使用してみますか?リレーションでレコードを返すかどうかをテストします。
Business.where(:user_id => current_user.id)
を呼び出すと、配列が取得されます。この配列にはオブジェクトがないか、1つまたは複数のオブジェクトが含まれている場合がありますが、nullにはなりません。したがって、check == nilは決して真になりません。
以下を試すことができます:
if Business.where(:user_id => current_user.id).count == 0
したがって、配列内の要素の数を確認し、それらをゼロと比較します。
またはあなたが試すことができます:
if Business.find_by_user_id(current_user.id).nil?
これは1またはnilを返します。
オブジェクトのインスタンス変数を使用する必要がある場合は、このようにします。
if @business = Business.where(:user_id => current_user.id).first
#Do stuff
else
#Do stuff
end
business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end