ActiveRecord 存在吗?与协会

问题描述 投票:0回答:6

我有以下 ActiveRecord 调用:

@payment = account.business.payments.find(params[:id])

它会在关联中搜索 id 为

payment
params[:id]
。但是,这会引发 RecordNotFound 异常。

我想调用

exists?
来查看记录是否存在以避免引发异常。这样做
Payment.exists?(account.business.payments.find(params[:id]))
不起作用。

我只想搜索

payments
那个
belong_to
那个
business
,而不是通过执行
Payment.exists?(:id => params[:id])
进行的所有付款。这样我就可以知道这是该特定帐户的企业付款。

我该怎么做?

注意:

account
has_one
business
business
has_many
payments

ruby-on-rails ruby activerecord
6个回答
12
投票

使用

where
而不是
find
,它将返回代表 0 条或更多记录的
ActiveRecord::Relation
,您可以从中链接
.exists?
:

@payments = account.business.payments.where(id: params[:id])


if @payments.exists?
  # ...
end

2
投票

如果您只需要检查是否存在:

account.business.payments.where(:id => params[:id]).exists?

如果您打算使用此记录,请调用

.first
而不是
exists?
,因为预计只有 1 条记录。顺便说一句,您也可以使用动态查找器(Rails 4 中已弃用)来执行此操作:

account.business.payments.find_by_id(params[:id])

如果不存在记录,这将返回

nil
(而不是爆炸)。


1
投票

您必须记住,使用

present?
会强制 ActiveRecord 从数据库加载整个集合,这显然并不总是理想的:

user.posts.present?
=>  SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 1 ORDER BY `sales`.`id` ASC

如果您想检查数据库中是否存在集合并且不需要数据,请使用

any?

user.posts.any?
=> SELECT 1 AS one FROM `posts` WHERE `posts`.`user_id` = 1 LIMIT 1

此外,不带任何参数的

exists?
any?

的作用相同
user.posts.exists?
=> SELECT 1 AS one FROM `posts` WHERE `posts`.`user_id` = 1

但是你可以用这个做更多的事情:https://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F


0
投票

如果我错了,有人可以否决,但我会建议

account.business.payments.where(:id => params[:id]).pluck(:id).present?

通过执行 pluck,您将跳过关联对象的实例化。 这意味着它们不必加载到内存中,如果您经常这样做,这将节省一些周期


0
投票

您可以将您的关联用于存在吗?

Business.find(business_id).payments.exists?(payment_id)

如果该企业存在付款,则应返回 true。


0
投票

更现代的解决方案是将

where
替换为
exists?
,如下所示:

object.association.exists?(attribute: "value")
© www.soinside.com 2019 - 2024. All rights reserved.