ruby-on-rails - view教程 - 创建rails项目
Ruby混合和调用超级方法 (4)
好吧,所以我一直在我的小Rails应用程序中重构我的代码,以消除重复,一般来说让我的生活更轻松(因为我喜欢简单的生活)。 这个重构的一部分,一直是将我的两个模型中通用的代码移动到一个模块,我可以将其包含在我需要的地方。
到现在为止还挺好。 看起来它会运行,但我刚刚遇到一个问题,我不知道如何解决。 该模块(我称之为“可发送”)只是处理传真,电子邮件或打印文档PDF的代码。 所以,例如,我有一个采购订单,我有内部销售订单(想象力缩写为ISO)。
我碰到的问题是,我想在加载对象后初始化一些变量(对于拼写不正确的人初始化:P),所以我一直在使用after_initialize钩子。 没问题,直到我开始添加一些mixin。
我所after_initialize
的问题是,我可以在任何一个after_initialize
中都有一个after_initialize
,所以我需要在开始时包含一个超级调用,以确保其他mixin after_initialize
调用被调用。 这真是太棒了,直到我打电话给超级电话,我得到一个错误,因为没有超级电话。
这里有一个小例子,如果我没有足够的困惑:
class Iso < ActiveRecord::Base
include Shared::TracksSerialNumberExtension
include Shared::OrderLines
extend Shared::Filtered
include Sendable::Model
validates_presence_of :customer
validates_associated :lines
owned_by :customer
order_lines :despatched # Mixin
tracks_serial_numbers :items # Mixin
sendable :customer # Mixin
attr_accessor :address
def initialize( params = nil )
super
self.created_at ||= Time.now.to_date
end
end
因此,如果每个mixin都有一个after_initialize调用,并且有一个超级调用,那么我怎样才能阻止最后一次超级调用? 在我打电话之前,如何测试超级方法的存在?
而不是检查超级方法是否存在,你可以定义它
class ActiveRecord::Base
def after_initialize
end
end
这在我的测试中起作用,不应该破坏你现有的任何代码,因为所有其他定义它的类都会默默地覆盖这个方法
你尝试过alias_method_chain
吗? 你可以基本上链接所有的after_initialize
调用。 它像一个装饰器:每个新的方法增加了一个新的功能层,并将控制权交给“重写”方法来完成剩下的工作。
你可以在这里抛出一个快速的条件:
super if respond_to?('super')
你应该没问题 - 不要添加无用的方法; 不错,干净。
你可以使用这个:
super if defined?(super)
这里是一个例子:
class A
end
class B < A
def t
super if defined?(super)
puts "Hi from B"
end
end
B.new.t