如何只删除Rails中存在的记录?

How to delete a record only if it exists in Rails?

我想在删除 post 本身时删除我为 post 创建的标记。但是如果令牌不存在,我不希望 Rails 抛出错误并停止执行。

现在,我就是这样做的。我认为这段代码太笨拙了。有什么巧妙的方法可以做到这一点吗?

DownloadToken.find_by_post_id(post.id).destroy unless DownloadToken.find_by_post_id(@post.id).nil?

这是一种方式(旧语法)

DownloadToken.find_by_post_id(post.id).try(:destroy)

rails 中的新语法:

DownloadToken.find_by(id: post.id).try(:destroy)

使用Ruby的安全导航运算符:

DownloadToken.find_by(id: post.id)&.destroy

看看你的Post型号; post.rb

即。

Class Post < ActiveRecord::Base
  has_many :download_tokens, dependent: :destroy
end

现在,当您删除 Post 对象时,无论关联如何; has_manyhas_one,它也会发现破坏dependent。在这种情况下,下载令牌

如果您确定可以使用其 destroy 方法处理 post 删除,那么您可以按照 进行操作,它会工作得很好。

如果您将在 post 上使用 delete 方法,您需要一些额外的功能来处理 download_tokens

class DownloadToken < ActiveRecord::Base
  def self.remove_post_tokens(the_post_id)
    where(post_id: the_post_id).destroy_all
  end
end

所以你的顺序是:

id = post.id
post.delete #or post.destroy
DownloadToken.remove_post_tokens(id)

这种情况并不纯粹是学术性的,因为相关的销毁操作可能非常昂贵,例如,如果您有太多 download_tokens,那么您不希望它与 [=12] 在同一个事务中=]的毁灭。

DownloadToken.find_by_post_id(post.id)&.destroy

仅当查询结果不是nil时才执行destroy。它是以下的缩写版本:

token = DownloadToken.find_by_post_id(post.id)
token.destroy if token