如何使用 rails 组织应用程序/模块中类的命名空间? [英] How I can organize namespace of classes in app/modules with rails?

查看:46
本文介绍了如何使用 rails 组织应用程序/模块中类的命名空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[这是如何模块化的后续问题Rails 模型?"]

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

Is there anyway to organize classes in app/models directory of Rails? Do I have to use single top-level namespace for all of the classes?

最初的动机是,我想把不是从 ActiveRecord::Base 继承的业务逻辑类放到 app/models 目录中.搜索此站点会发现许多建议将业务逻辑类放在 app/models 目录中的答案.我发布了一个不同的问题,并得到了可以放置这样的建议类进入 lib 目录.

Initial motivation is, I want place business logic classes which do not inherited from ActiveRecord::Base into app/models directory. Searching this site reveals many answers which recommend to place business logics classes in the app/models directory. I posted a different question, and got recommendation that it is possible to place such classes into lib directory.

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

Now I'm curious. I'd like to place these classes into different namespace and directory in apps/models directory which recommended by others. Is it possible?

实际上,我对此进行了实验,但在我看来,这不是 Rails 所期望的.如果我创建这样一个类(如 some_mod_name/class_in_mod.rb 中的 SomeModName::ClassInMod ),它不会被加载.另外,我在模块内定义了常量.因为它们没有加载,所以我不能使用它们.实际上,使用 rspec 它可以正常工作,但是使用 rails server,该类不会加载.我确定这与自动加载问题有关.

Actually, I experiment that, but it seems to me that is what rails is not expected. If I create such a class (like SomeModName::ClassInMod in some_mod_name/class_in_mod.rb ) it does not get loaded. Also, I defined constants inside the module. Since they're not loaded, I can't use them. Actually, with rspec it work without problem, but with rails server, the class does not loaded. I'm sure it is related to autoloading issue.

除了上面提到的类之外,从ActiveRecord::Base 继承的类可以放在module 内的一些命名空间中.我也很好奇这是否有效.

In addition to the classes mentioned above, classes inherited from ActiveRecord::Base can be placed into some namespaces inside a module. I'm curious whether this work well or not too.

换句话说,问题是:我可以通过配置加载这些文件来让 rails 开心,还是不是 rails 的设计方式?

So the question in other words: can I make rails happy by configuring these files to be loaded, or is not the way rails designed?

推荐答案

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

Yes, you can define an ActiveRecord class in a module. The easy way is to use the generator:

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

注意,Rails 会额外创建一个包含模块定义的文件.在这种情况下:

Observe, that Rails will create additionally a file with the definition of the module. In this case:

# 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)的一个非常重要的部分 - 特别是对于那些在编译语言方面有很强背景的人 - 要记住 没有编译阶段,所以定义只有在使用特定类时才会读取和执行某个类的.有时在应用服务器启动并处理数千个请求后一周.

Your problems with constants defined in the module were caused by the fact, that you defined the constants in the definition module "wrapped" around only one model, from the two you have created. A very important part in understanding ruby (and Rails) - especially for people who have strong background in compiled languages - is to remember that there is no compilation phase, so the definition of some class is read and executed only when that specific class is used. Sometimes a week after the application server has been started and served thousands of requests.

因此,正如我在上一个问题的回答中所说,自动加载的问题在于有时常量的定义在尝试使用它们的定义之后被读取.顺序是随机的——如果第一个使用的对象恰好是 EvaluationLogic,那么就会出现错误.第一个对象碰巧是PhaseLogic,一切都很好.

Thus, as I said in the previous question's answer, the problem with autoloading was that sometimes the definition of the constants was read after the definition which was trying to use them. The order was random - if the first used object happened to be EvaluationLogic, then the error emerged. It the first object happened to be PhaseLogic, everything was fine.

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

Now, when you have a file for the module itself, and define constants in that file (app/models/logic.rb), autoloading will be able to find and execute the definitions before any class starts to use them. I hope everything will be OK.

这篇关于如何使用 rails 组织应用程序/模块中类的命名空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆