自己实现它(而不是使用 gem)。它比一开始看起来要容易得多,而且它也没有任何改变方法含义的宝石那么复杂destroy
,在我看来,这是一个坏主意。
我并不是说使用 gem 本身很复杂——我是说通过改变destroy
方法的含义,你正在改变 Rails 世界中人们认为理所当然的东西的含义——当你调用destroy
该记录时会消失,destroy
如果它们通过dependent: destroy
回调链接在一起,也可能会在依赖对象上调用。
更改 的含义destroy
也很糟糕,因为在“约定优于配置”的世界中,当您违反约定时,您实际上是在破坏 Rails 代码的“自动性”。所有这些你认为理所当然的东西,因为你阅读了一段 Rails 代码,并且你知道某些假设通常适用——那些已经过时了。当您以不明显的方式更改这些假设时,您几乎肯定会因此而引入一个错误。
不要误会我的意思,没有什么比实际阅读代码来检查您的假设更好的了,但作为一个社区,能够谈论某些事情并通常让他们的行为以某种方式行事也很好。
考虑以下:
- Rails 中没有规定必须
destroy
在控制器中实现动作,所以不要这样做。这是标准操作之一,但不是必需的。
- 使用该
update
操作设置和清除archived
布尔属性(或类似名称)
- 我使用了
acts_as_paranoid
gem,如果您需要在模型中添加任何范围(除了 gem 提供的范围),您将发现自己不得不绕过它,关闭默认的“隐藏存档记录” " 范围,当你遇到它时,它几乎立即失去了它的价值。此外,该 gem 本身几乎什么都不做,而且它的功能可以很容易地自己编写(我的意思是只比安装 gem 本身做更多的工作),所以从这个角度来看使用它确实没有任何好处。
- 如前所述,重写方法或动作是一个坏主意,因为它打破了 Rails(和 ActiveRecord)关于调用对象
destroy
意味着什么的约定。destroy
任何这样做的宝石(acts_as_paranoid
例如)也打破了这个惯例,你最终会混淆自己或其他人,因为destroy
根本不会意味着它应该意味着什么。这会给您的代码增加混乱,而不是清晰。不要这样做——你以后会付钱的。
- 如果您想使用软删除 gem,因为您要防止一些理论上的、未来的开发人员可能会占用您的数据……那么,最好的解决方案是不要雇用这些人或与这些人一起工作。没有经验的人需要指导,而不是防止他们犯错的宝石。
- 如果你真的,绝对,必须防止破坏给定模型的记录(除了能够简单地归档它),然后使用
before_destroy
回调并简单地返回 false,这将防止它被破坏,除非显式调用delete
被使用(无论如何都与破坏不同)。此外,有了回调就可以(a)很明显为什么destroy
不改变其含义就不能工作,并且(b)很容易编写测试以确保它不可破坏。这意味着将来,如果您不小心删除了该回调或执行其他使该模型可销毁的操作,则测试将失败,并提醒您注意这种情况。