你如何确保has_many总是“有一个最小”?

假设我正在编写代码来建模公交车站。

每个公交fleet总是至少有bus 。 我想弄清楚在模型中强制执行此最小数字的最佳方法。 除非舰队本身被摧毁,否则舰队中的最后一辆公共汽车永远不会被毁坏。

一种方法是捕获bus对象上的关系。

 class Bus ... before_destroy :check_minimum_busses_on_parent end 

然而,这普遍忽视了单一责任原则。 公共汽车正在处理不是问题的车队问题。

我可以使用before_destroy方法创建一个bus_observer 。 现在一切都是单一的责任,感觉就像我们有更多的物体在不必要的时候发出嘎嘎声。

 class BusObserver < ActiveRecord::Observer def before_destroy bus false if bus.fleet.busses.count <= 1 end end 

这肯定会起到作用,但我对于它真正属于Fleet类的脱钩并不是百分之百。

仍然允许舰队摧毁它的最后一class车

为了允许父fleet对象本身可能被摧毁并想要摆脱它的最后一辆公共汽车的可能性,我最终还需要一些交叉通信,所以公共汽车可以弄清楚舰队是否也得到了印章:

 class BusObserver < ActiveRecord::Observer def before_destroy bus if bus.fleet.busses.count <= 1 false unless bus.fleet.currently_being_destroyed? end end end 

这显然进入了纯粹丑陋的境界。 可以将它包装成方法.bus_can_be_destroyed? 坐在舰队对象上,但这并不是更好。

得到我所追求的最简洁的方法是什么?

你有一个Decommissioner类,给定一个总线,适当地处理业务逻辑? 这似乎是清楚和合理的。

如果您对记录退役事件感兴趣,它甚至可以是ActiveRecord模型。

有点像:

 class BusDecommissioner def initialize(bus) @bus = bus end def decommissionable? @bus.fleet.buses.size > 1 end def decommission! @bus.destroy if decommissionable? end end 

它会与协会回调一起使用吗? 根据文档,您可以使用before_remove回调并停止删除。