Rails 4:如何在不给模型命名空间的情况下将Rails模型组织在子路径中?

81

能否有类似这样的东西?

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

目标是更好地组织/app/models文件夹,但不需要对模型进行命名空间处理。

Rails 3中一个未解决的问题在这里:Rails 3.2.9和子文件夹中的模型

通过命名空间指定table_name似乎可以工作(请参见Rails 4模型子文件夹),但我想在不使用命名空间的情况下完成此操作


我明白你不想要命名空间,但我认为最好的方法是使用ActiveSupport Concerns。 - Nando Sousa
2
@NandoSousa。不,ActiveSupport Concerns 用于共享行为。这是您使用模型的方式。 - berkes
1个回答

117

默认情况下,Rails不会将models目录的子文件夹添加到autoload路径中。这就是为什么它只能找到有命名空间的models--命名空间说明要查找的子目录。

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

config.autoload_paths += Dir[Rails.root.join("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 的评论 获取详细信息。


6
尝试了一下,但出现了“无法自动加载常量User::Credits”的错误,期望/srv/books/app/models/user/credits.rb来定义它。因此,仍需要对文件进行命名空间处理。按建议将它们放置在lib条目上方。 - Rubytastic
1
这个错误实际上是好消息。它意味着找到了文件。但是,你在这里使用了奇怪的复数形式。如果你的文件名是 app/models/user/credits.rb,那么请确保文件中的类名也是复数形式:class Credits。但是,我建议使用 Rails 的标准,将其命名为 class Credit,并将文件名命名为 app/models/user/credit.rb(模型应该是单数形式)。无论哪种方式,这应该是问题所在。让我知道! - pdobb
1
在Rails 4.1配置中,我使用config.autoload_paths += %W( #{Rails.root}/app/models/namespace #{Rails.root}/app/models/other_namespace ) - Epigene
14
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')] 可行,但会减慢应用程序的速度,特别是在经常重新加载应用程序的开发模式下。原因是您不应将所有文件添加到autoload_paths中,而只应添加可以从中推断出文件名称和模块的根文件夹。简单地说,如果您的models中只有一级子文件夹且没有命名空间,则只需执行 config.autoload_paths += Dir[Rails.root.join('app', 'models', '*/')] 来添加仅第一级子目录。同样适用于 lib 或其他路径。 - muichkine
3
@pdobb 这是经验 :) 如果你查看自动加载的工作原理,你会发现它会循环遍历所有auto_loading_paths,并向其中添加模型的推论。例如,如果你有NameSpace::Model,它会尝试在所有的autoload_paths中寻找 path/namespace/model。当且仅当 path 是一个目录时才能匹配成功。一般来说,为了达到最大效率,你应该只将目录放入autoload_paths中。希望这可以帮助到你。 - muichkine
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接