97

In my app a User can create a Business. When they trigger the index action in my BusinessesController I want to check if a Business is related to the current_user.id:

  • If yes: display the business.
  • If no: redirect to the new action.

I was trying to use this:

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

But it always returns true even when the business doesn't exist...

How can I test if a record exists in my database?

4

7 回答 7

247

为什么你的代码不起作用?

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

某些 linter(例如 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
于 2013-05-22T02:53:00.380 回答
29

在这种情况下,我喜欢使用exists?ActiveRecord 提供的方法:

Business.exists? user_id: current_user.id
于 2013-06-26T17:34:08.183 回答
5

与“存在?”:

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?
于 2013-08-21T09:39:19.203 回答
1

当你打电话时,Business.where(:user_id => current_user.id)你会得到一个数组。此 Array 中可能没有对象或一个或多个对象,但它不会为空。因此 check == nil 永远不会是真的。

您可以尝试以下方法:

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

因此,您检查数组中的元素数量并将它们与零进行比较。

或者您可以尝试:

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

这将返回一或零。

于 2013-05-22T03:07:09.003 回答
1

ActiveRecord#where 将返回一个 ActiveRecord::Relation 对象(永远不会为零)。尝试使用 .empty?在关系上测试它是否会返回任何记录。

于 2013-05-22T03:01:37.607 回答
1
business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end
于 2015-03-19T11:06:08.543 回答
0

如果您需要使用对象的实例变量,我会这样做:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
于 2016-03-16T15:45:40.230 回答