什么是重写Rails的ActiveRecord的破坏行为的最好方法是什么? [英] What is the best way to override Rails ActiveRecord destroy behavior?

查看:159
本文介绍了什么是重写Rails的ActiveRecord的破坏行为的最好方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在哪里,我想重写摧毁了我的许多模型的行为的应用程序。用例是,用户可能确实需要删除特定的记录,但实际上从数据库中删除的行会破坏参照完整性,影响到其他相关的模型。例如,该系统的用户可能想要删除与他们不再做商业客户,但要维持与该客户需要的交易。

I have an application where I would like to override the behavior of destroy for many of my models. The use case is that users may have a legitimate need to delete a particular record, but actually deleting the row from the database would destroy referential integrity that affects other related models. For example, a user of the system may want to delete a customer with whom they no longer do business, but transactions with that customer need to be maintained.

看来我至少有两个选项:

It seems I have at least two options:

  1. 在复制数据到一定模式有效地非规范化我的数据模型,使删除的记录不会影响到相关的数据。
  2. 覆盖的ActiveRecord的破坏的行为做类似设置一个标志,指示用户已删除的记录,并使用该标志来隐藏记录。

我缺少一个更好的办法?

Am I missing a better way?

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

Option 1 seems like a horrible idea to me, though I'd love to hear arguments to the contrary.

选项2似乎有点Rails的十岁上下,但我不知道处理它的最佳方式。我应该创建一个继承的ActiveRecord :: Base的我自己的父类,覆盖破坏的方法有,然后从该类的继承车型,我想这种行为?我应该也覆盖取景器行为,以便记录标记为删除默认情况下不回来了?

Option 2 seems somewhat Rails-ish but I'm wondering the best way to handle it. Should I create my own parent class that inherits from ActiveRecord::Base, override the destroy method there, then inherit from that class in the models where I want this behavior? Should I also override finder behavior so records marked as deleted aren't returned by default?

如果我这样做,我将如何处理动态发现者?那么命名范围?

If I did this, how would I handle dynamic finders? What about named scopes?

推荐答案

如果你没有在再见到这些记录真正感兴趣,而只关心孩子当父被销毁依然存在,作业很简单:增加:依赖=> :废止的has_many 调用设置引用父 NULL 在破坏自动,并教的观点来处理该引用是缺少的。然而,这只是工作,如果你没问题不是曾经看到该行再次,也就是查看这些交易显示[不复存在]下的公司名称。

If you're not actually interested in seeing those records again, but only care that the children still exist when the parent is destroyed, the job is simple: add :dependent => :nullify to the has_many call to set references to the parent to NULL automatically upon destruction, and teach the view to deal with that reference being missing. However, this only works if you're okay with not ever seeing the row again, i.e. viewing those transactions shows "[NO LONGER EXISTS]" under company name.

如果您的执行的希望再次看到这些数据,这听起来像你想要什么无关,与真正的破坏的记录,这意味着你将永远不需要再次提及他们。隐藏似乎是要走的路。

If you do want to see that data again, it sounds like what you want has nothing to do with actually destroying records, which means that you will never need to refer to them again. Hiding seems to be the way to go.

相反压倒一切毁灭,因为你没有真正销毁记录,似乎显著简单的​​把你的行为在隐藏方法触发一个标志,因为你的建议。

Instead of overriding destroy, since you're not actually destroying the record, it seems significantly simpler to put your behavior in a hide method that triggers a flag, as you suggested.

在那里,只要你想列出这些记录,只包括可见的记录,一个简单的解决方案是包括可见范围不包括隐藏的记录,并不包括它,当你想再次找到具体的,隐藏的记录。另一种途径是使用 default_scope 隐藏隐藏的记录,并使用 Model.with_exclusive_scope {找到(ID)} 拉涨一个隐藏的纪录,但我建议你反对它,因为它可能是一个严重的疑难杂症为传入的开发,并从根本上改变什么 Model.all 返回一点都没有体现该方法调用显示什么。

From there, whenever you want to list these records and only include visible records, one simple solution is to include a visible scope that doesn't include hidden records, and not include it when you want to find that specific, hidden record again. Another path is to use default_scope to hide hidden records and use Model.with_exclusive_scope { find(id) } to pull up a hidden record, but I'd recommend against it, since it could be a serious gotcha for an incoming developer, and fundamentally changes what Model.all returns to not at all reflect what the method call suggests.

我的理解,使渴望控制器看起来像他们正在做的事情Rails的方式,但如果你不是的真正的处事方式Rails的,所以最好是明确一下,特别是当它真的没有那么多的痛苦这样做。

I understand the desire to make the controllers look like they're doing things the Rails way, but when you're not really doing things the Rails way, it's best to be explicit about it, especially when it's really not that much of a pain to do so.

这篇关于什么是重写Rails的ActiveRecord的破坏行为的最好方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆