子文件夹中的子类模型不会自动加载

时间:2014-06-25 05:38:48

标签: ruby-on-rails ruby ruby-on-rails-3

我的一些模型有两个级别的继承:(全部在/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/**/"]

提前致谢!

3 个答案:

答案 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,以便在重新启动应用时运行初始值设定项。