[这是“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设计的方式吗?
答案 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
)时,自动加载将能够在任何类开始之前找到并执行定义使用它们。我希望一切都会好的。