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

77 activerecord ruby-on-rails exists ruby-on-rails-3

在我的应用程序中,用户可以创建业务.当他们触发index我的行动时,我BusinessesController想检查一个企业是否与以下内容相关current_user.id:

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

我试图用这个:

if Business.where(:user_id => current_user.id) == nil
  # no business found
end
Run Code Online (Sandbox Code Playgroud)

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

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

MrY*_*iji 212

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

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
Run Code Online (Sandbox Code Playgroud)

如何测试是否存在至少一条记录?

选项1:使用.exists?

if Business.exists?(user_id: current_user.id)
  # same as Business.where(user_id: current_user.id).exists?
  # ...
else
  # ...
end
Run Code Online (Sandbox Code Playgroud)

选项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
Run Code Online (Sandbox Code Playgroud)

选项3: if语句中的变量赋值

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

这个选项可以被认为是某些短号的代码气味(例如Rubocop).

选项3b:变量赋值

business = Business.where(user_id: current_user.id).first
if business
  # ...
else
  # ...
end
Run Code Online (Sandbox Code Playgroud)

您也可以使用.find_by_user_id(current_user.id)而不是.where(...).first


最佳选择:

  • 如果您不使用Business对象:选项1
  • 如果您需要使用Business对象:选项3


Ham*_*med 26

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

Business.exists? user_id: current_user.id
Run Code Online (Sandbox Code Playgroud)


小智 5

与“存在?”:

Business.exists? user_id: current_user.id #=> 1 or nil
Run Code Online (Sandbox Code Playgroud)

与“任何?”:

Business.where(:user_id => current_user.id).any? #=> true or false
Run Code Online (Sandbox Code Playgroud)

如果你使用.where 的东西,一定要避免作用域的问题,最好使用 .unscoped

Business.unscoped.where(:user_id => current_user.id).any?
Run Code Online (Sandbox Code Playgroud)