你如何确保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
回调并停止删除。