覆盖 Rails ActiveRecord 销毁行为的最佳方法是什么?

2024-05-08

我有一个应用程序,我想在其中覆盖许多模型的销毁行为。用例是用户可能有删除特定记录的合法需要,但实际上从数据库中删除该行会破坏引用完整性,从而影响其他相关模型。例如,系统的用户可能想要删除不再与其有业务往来的客户,但需要维护与该客户的交易。

看来我至少有两个选择:

  1. 将数据复制到必要的模型中,有效地对我的数据模型进行非规范化,以便删除的记录不会影响相关数据。
  2. 覆盖 ActiveRecord 的“销毁”行为以执行诸如设置指示用户“删除”记录的标志并使用此标志隐藏记录之类的操作。

我是否缺少更好的方法?

选项 1 对我来说似乎是一个可怕的想法,尽管我很想听到相反的论点。

选项 2 看起来有点像 Rails,但我想知道处理它的最佳方法。我是否应该创建自己的从 ActiveRecord::Base 继承的父类,重写那里的 destroy 方法,然后从我想要此行为的模型中的该类继承?我是否还应该覆盖查找器行为,以便默认情况下不会返回标记为已删除的记录?

如果我这样做,我将如何处理动态查找器?命名范围怎么样?


如果您实际上不想再次查看这些记录,而只关心当父级被销毁时子级仍然存在,那么工作很简单:添加:dependent => :nullify to the has_many调用以设置对父级的引用NULL销毁时自动执行,并教导视图处理丢失的引用。但是,只有当您同意不再看到该行时,这才有效,即查看这些交易在公司名称下显示“[不再存在]”。

If you do想再次查看该数据,听起来您想要的与实际无关破坏记录,这意味着您将永远不需要再次引用它们。隐藏似乎是一条出路。

由于您实际上并未销毁记录,因此不必重写 destroy ,将您的行为放入 a 中似乎要简单得多hide正如您所建议的,触发标志的方法。

从那里开始,每当您想要列出这些记录并且仅包含可见记录时,一个简单的解决方案是包含visible不包含隐藏记录的范围,并且当您想要再次查找特定的隐藏记录时,不要包含它。另一条路径是使用default_scope隐藏隐藏记录并使用Model.with_exclusive_scope { find(id) }调出隐藏记录,但我建议不要这样做,因为这对于新来的开发人员来说可能是一个严重的问题,并且从根本上改变了Model.all返回根本不反映方法调用的建议。

我理解让控制器看起来像以 Rails 方式做事的愿望,但是当你不这样做时really以 Rails 方式做事,最好明确说明,尤其是当这样做实际上并不是那么痛苦的时候。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

覆盖 Rails ActiveRecord 销毁行为的最佳方法是什么? 的相关文章

随机推荐