Rails 4:在没有命名空间模型的子路径中组织 Rails 模型?

Posted

技术标签:

【中文标题】Rails 4:在没有命名空间模型的子路径中组织 Rails 模型?【英文标题】:Rails 4: organize rails models in sub path without namespacing models? 【发布时间】:2013-09-26 20:46:34 【问题描述】:

有可能有这样的东西吗?

app/models/
app/models/users/user.rb
app/models/users/education.rb

目标是更好地组织 /app/models 文件夹,但不必为模型命名。

Rails 3 的一个未回答的问题在这里: Rails 3.2.9 and models in subfolders.

使用命名空间指定 table_name 似乎可行(请参阅Rails 4 model subfolder),但我想在没有命名空间的情况下这样做

【问题讨论】:

我知道您不需要命名空间,但我认为最好的方法是使用 ActiveSupport Concerns。 @NandoSousa。否。ActiveSupport 问题是针对共享行为的。你使用模型的方式。 【参考方案1】:

默认情况下,Rails 不会将模型目录的子文件夹添加到自动加载路径中。这就是为什么它只能找到命名空间模型的原因——命名空间照亮了要查看的子目录。

要将 app/models 的所有子文件夹添加到自动加载路径,请将以下内容添加到 config/application.rb

config.autoload_paths += Dir[Rails.root.join("app", "models", "*/")]

或者,如果您有一个更复杂的 app/models 目录,上述将 app/models 的所有子文件夹组合在一起的方法可能无法正常工作。在这种情况下,您可以通过更明确一些并仅添加您指定的子文件夹来解决此问题:

config.autoload_paths += Rails.root.join("app", "models", "<my_subfolder_name1>")
config.autoload_paths += Rails.root.join("app", "models", "<my_subfolder_name2>")

Rails 4.1+ 更新

从 Rails 4.1 开始,应用程序生成器默认不包含 config.autoload_paths。所以,请注意,以上内容确实属于 config/application.rb

更新

修复了上述代码中的自动加载路径示例以使用*/ 而不是**。请务必阅读 muichkine's comment 了解有关此内容的详细信息。

【讨论】:

试过了,但它失败了,因为无法自动加载常量 User::Credits,需要 /srv/books/app/models/user/credits.rb 来定义它。所以它仍然不希望文件被命名为间隔。按照建议将它们放在 lib 条目上方。 这个错误其实是个好消息。这意味着它找到了文件。但是,你在这里使用了一个奇怪的复数形式。如果您的文件名是app/models/user/credits.rb,请确保文件中的类名也是复数:class Credits。但是,我建议使用 Rails 标准并将其设为class Credit,文件名为app/models/user/credit.rb(模型应该是单数)。不管怎样,这应该是问题所在。告诉我! 在 Rails 4.1 配置中我使用config.autoload_paths += %W( #Rails.root/app/models/namespace #Rails.root/app/models/other_namespace ) config.autoload_paths += Dir[Rails.root.join('app', 'models', '**')] 工作但会减慢应用程序的速度,特别是在应用程序经常重新加载的开发模式下。原因是您不能将所有文件添加到 autoload_paths 中,而只能添加可以从中推断文件名和模块的根文件夹。简单来说,如果模型中只有一层子文件夹而没有命名空间模型,则应该只添加config.autoload_paths += Dir[Rails.root.join('app', 'models', '*/')],它只添加第一层子目录。 lib 或其他路径相同。 @pdobb 这是经验 :) 如果您查看自动加载是如何工作的,您会发现它完全循环 auto_loading_paths 并在其中添加了模型的推理。例如,如果您有NameSpace::Model,它将尝试在所有自动加载路径中找到path/namespace/model。这显然只有在path 是一个目录时才能匹配。根据经验,您应该只在autoload_paths 中拥有目录,以获得最大效率。希望对您有所帮助。

以上是关于Rails 4:在没有命名空间模型的子路径中组织 Rails 模型?的主要内容,如果未能解决你的问题,请参考以下文章

删除存在于另一个命名空间 rails 中的模型

命名空间模型中的 Rails 关联

Rails url_for 和命名空间模型

在控制器中找不到命名空间内的 Ruby on Rails 模型

Rails 中的命名空间模型:联合的状态是啥?

如何避免Rails 5嵌套资源命名空间路由中的双下划线