检查Rails中控制器是否存在记录

时间:2013-05-22 02:49:13

标签: ruby-on-rails ruby-on-rails-3 activerecord exists

在我的应用中,用户可以创建商家。当他们在index中触发BusinessesController操作时,我想检查商家是否与current_user.id相关:

  • 如果是:显示业务。
  • 如果否:重定向到new操作。

我试图用这个:

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

但即使业务不存在,它也总是会返回......

如何测试数据库中是否存在记录?

7 个答案:

答案 0 :(得分:205)

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

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

答案 1 :(得分:24)

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

Business.exists? user_id: current_user.id

答案 2 :(得分:4)

与'存在?':

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?

答案 3 :(得分:1)

ActiveRecord#将返回一个ActiveRecord :: Relation对象(永远不会是nil)。尝试使用.empty?关于测试是否会返回任何记录的关系。

答案 4 :(得分:1)

当你致电Business.where(:user_id => current_user.id)时,你会得到一个数组。此Array可能没有对象或其中的一个或多个对象,但它不会为null。因此,检查== nil将永远不会成立。

您可以尝试以下操作:

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

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

或者您可以尝试:

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

这将返回一个或零。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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