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

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

问题描述:

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

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:

  • 如果是:显示商家.
  • 如果否:重定向到 new 操作.

我正在尝试使用它:

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

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

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

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

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

where 方法返回一个 ActiveRecord::Relation 对象(就像一个包含 where 的结果的数组),它可以是空的,但它永远不会是nil.

The where method returns an ActiveRecord::Relation object (acts like an array which contains the results of the where), it can be empty but it will never be 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 语句中的变量赋值


Option 3: Variable assignment in the if statement

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

此选项可能被某些 linter(例如 Rubocop)视为代码异味.

This option can be considered a code smell by some linters (Rubocop for example).

选项 3b:变量赋值

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

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

You can also use .find_by_user_id(current_user.id) instead of .where(...).first

最佳选择:

  • 如果您不使用 Business 对象:选项 1
  • 如果您需要使用 Business 对象:选项 3
  • If you don't use the Business object(s): Option 1
  • If you need to use the Business object(s): Option 3