我正在使用active_record-acts_as
gem在我的rails应用程序中实现多表继承。这个gem帮助子类像父类一样运行,因此它响应父类的方法。我想让父类也响应子类的方法,因为它简化了路由。
到目前为止,我有:
class ParentClass < ActiveRecord::Base
actable as: :assetable
def method_missing_with_specific(method, *args, &block)
# specific is the associated child class instance
if specific.respond_to?(method)
specific.send(method, *args, &block)
else
method_missing_without_specific(method, *args, &block)
end
end
alias_method_chain :method_missing, :specific
def is_a_with_specific?(type)
if assetable_type.constantize == type
true
else
is_a_without_specific?(type)
end
end
alias_method_chain :is_a?, :specific
end
这很有效,但我在实施respond_to?
方法时无法使用method_missing
方法。
我试过了:
def respond_to?(method, private=false)
super || specific.respond_to?(method, private)
end
和
def respond_to_with_specific?(method, private=false)
if specific.respond_to?(method, private)
true
else
respond_to_without_specific?(method, private)
end
end
alias_method_chain :respond_to?, :specific
这两种方法都导致我的测试失败:
Failure/Error: Unable to find matching line from backtrace
SystemStackError:
stack level too deep
# /Users/blueye/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.2/lib/active_record/transactions.rb:286
#
# Showing full backtrace because every line was filtered out.
# See docs for RSpec::Configuration#backtrace_exclusion_patterns and
# RSpec::Configuration#backtrace_inclusion_patterns for more information.
显然,我在与ActiveRecord
交互时会产生某种无限递归,但我不确定如何。
在这种情况下如何实施respond_to?
?
更新
我在gem中找到了以下代码:
def respond_to?(name, include_private = false)
super || acting_as.respond_to?(name)
end
这似乎会创建某种循环逻辑,其中每个类都将respond_to?
委托给另一个。我尝试在子类中重写此方法,但调用super
似乎只是委托gem模块中包含的方法。
答案 0 :(得分:1)
您在respond_to?
方法中调用respond_to_with_specific?
,因此无限递归。
由于Child类应该具有Parents类 plus 的所有方法,所以你应该能够做到:
def respond_to_with_specific?(method, private=false)
specific.respond_to_without_specific?(method, private)
end