我的一些模型有两个级别的继承:(全部在/app/models
)
A.rb
/A/B1.rb
/A/B1/C1.rb
/A/B1/C2.rb
/A/B1/C3.rb
/A/B2.rb
/A/B2/C1.rb
/A/B2/C2.rb
/A/B2/C3.rb
...
A.rb很简单:
class A
def self.inherited(subclass)
puts "New subclass: #{subclass}"
end
# some methods
end
B1.rb是:
class A::B1 < A
# some methods
end
C1.rb是:
class A::B1::C1 < A::B1
# some methods
end
您可以插入其余模型的外观。
当我加载rails console
时,我看到了这一点:
New subclass: A::B1
New subclass: A::B1::C1
New subclass: A::B2
请注意 A :: B1 :: C2,A :: B1 :: C3,并且没有A :: B2子类被继承!那是为什么?
它变得更加怪异。在rails console
中,我可以这样做:
irb(main)> A::B1::C2
New subclass: A::B1::C2
A::B1::C2 < A::B1
irb(main)> A::B2::C1
New subclass: A::B2::C1
A::B2::C1 < A::B2
因此,我可以键入所有未继承的子类,然后突然触发puts
消息。我认为这证明问题出在自动加载器上,而不是我的代码。
使用Ruby 1.9在我的开发环境中发生这种情况。和Rails 3.2。
以下是我的config.autoload_paths
声明:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
提前致谢!
答案 0 :(得分:1)
您需要在config.autoload_paths
选项中加入各种模型:
#config/application.rb
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
这使用globbing - 基本上将特定目录中的任何文件添加到您的路径中。我们将上述代码用于单级目录(app/models/directory/1.rb
);如果你想使用多个级别,你必须像这样表明:
Dir[Rails.root.join('app', 'models', '{*}', '{**}')]
答案 1 :(得分:0)
我希望我有更好的答案,但对于Sergio的观点,我的子类从未被直接提及,因此它们不会被自动加载。
我真的必须把它们写在我的类文件的顶部:
B1.rb:
class A1::B1
A1::B1::C1 # simply mentioning the class autoloads it
A1::B2::C2
...
def foo
...
end
end
答案 2 :(得分:0)
这可能为时已晚,无法帮助您,但我遇到了同样的问题,所以希望这个答案可以帮助其他人。
如果您使用的是Spring
gem,那么您的应用程序实际上是在后台运行。因此,只需重新启动即可重新运行初始化程序,并且不会将这些目录添加到自动加载路径中。
您希望运行bin/spring stop
,以便在重新启动应用时运行初始值设定项。