如何使用rails组织app / modules中的类的命名空间?

时间:2012-03-15 00:40:25

标签: ruby-on-rails-3

[这是“How I can modularize Rails model?”的后续问题。

有没有在Rails的app/models目录中组织类? 我是否必须为所有类使用单个顶级命名空间?

最初的动机是,我希望将不从ActiveRecord::Base继承的业务逻辑类放到app/models目录中。搜索此站点会显示许多答案,建议将业务逻辑类放在app/models目录中。我发布了a different question,并建议可以将这些类放入lib目录。

现在我很好奇。我想将这些类放在apps/models目录中不同的名称空间和目录中,这是其他人推荐的。有可能吗?

实际上,我对此进行了实验,但在我看来,轨道不是预期的。如果我创建这样的类(如some_mod_name / class_in_mod.rb中的SomeModName :: ClassInMod),则不会加载它。另外,我在模块中定义了常量。由于它们没有装载,我不能使用它们。实际上,使用rspec它可以正常工作,但使用rails server时,类不会加载。我确定它与自动加载问题有关。

除了上面提到的类之外,从ActiveRecord::Base继承的类可以放在module内的某些名称空间中。我很好奇这项工作是否合适。

换句话说,问题是:我可以通过配置这些要加载的文件来实现轨道,或者不是rails设计的方式吗?

1 个答案:

答案 0 :(得分:6)

是的,您可以在模块中定义ActiveRecord类。简单的方法是使用生成器:

./script/rails generate model logic/phase_logic
./script/rails generate model logic/evaluation_logic

观察,Rails将另外创建一个包含模块定义的文件。在这种情况下:

# app/models/logic.rb
module Logic
  ...
end

# app/models/logic/phase_logics.rb
class Logic::PhaseLogic < ActiveRecord::Base
  ...
end

# app/models/logic/evaluation_logics.rb
class Logic::EvaluationLogic < ActiveRecord::Base
  ...
end

您在模块中定义的常量问题是由于您定义了定义模块中的常量“包裹”在您创建的两个模型周围的事实引起的。理解ruby(和Rails)的一个非常重要的部分 - 特别是对于具有强大编译语言背景的人 - 是要记住没有编译阶段,所以定义只有在使用该特定类时才会读取和执行某些类的操作。在应用程序服务器启动并提供数千个请求后,有时一周

因此,正如我在previous question的回答中所说的那样,自动加载的问题在于,有时在试图使用它们的定义之后读取了常量的定义。顺序是随机的 - 如果第一个使用的对象碰巧是EvaluationLogic,则出现错误。它的第一个对象恰好是PhaseLogic,一切都很好。

现在,当你有一个模块本身的文件,并且在该文件中定义常量app/models/logic.rb)时,自动加载将能够在任何类开始之前找到并执行定义使用它们。我希望一切都会好的。