我正在尝试在Ruby和ActiveRecord中实现一个多态对象的责任链模式。我遇到了一些问题。
以下是一个例子:
class Hospital
has_one :setting, :as => :settable
belongs_to :administrative_area
def next_link
adminstrative_area
end
def usable_setting
setting ? setting : next_link.usable_setting
end
end
然后,我有一个Setting对象:
class Setting < ActiveRecord::Base
belongs_to :settable, :polymorphic => true
def chained
%w(api_key active_days).each do |method|
# this is here because otherwise the method isn't defined,
# it's almost as while it's going up, the metaclass doesn't have the columns
# until it loads, probably will be fixed if we cache classes
self.send method.to_sym
(class << self; self; end).class_eval do
define_method method do |*args|
alias_method "original_#{method}", method
my_setting = send("original_#{method}")
if my_setting.nil? or my_setting.empty?
settable.next_link.usable_setting.chained.send(method)
else
return my_setting
end
end
end
end
self
end
end
答案 0 :(得分:1)
你似乎过于复杂。似乎您正在尝试查看api_key和active_days是否存在,如果不存在,则从其他地方获取它。
这是正确的方法,假设api_key和active_days是表中的列:
class Setting < ActiveRecord::Base
belongs_to :settable, :polymorphic => true
def api_key
super || settable.next_link.usable_setting.api_key
end
def active_days
super || settable.next_link.usable_setting.active_days
end
end
您可以稍微重构一下以保持清晰并删除重复。
class Setting < ActiveRecord::Base
belongs_to :settable, :polymorphic => true
def api_key
super || next_usable_setting.api_key
end
def active_days
super || next_usable_setting.active_days
end
private
def next_usable_setting
settable.next_link.usable_setting
end
end
所以在这种情况下通知 - 如果你有api_key / active_days可用,它将被返回。 Otehrwise,它将从next_link获取useful_setting。如果那个有api_key / active_days,它将被返回,否则它将从next_link获取useful_setting。等