rails 4:将 routes.rb 拆分为多个较小的文件
Posted
技术标签:
【中文标题】rails 4:将 routes.rb 拆分为多个较小的文件【英文标题】:rails 4: split routes.rb into multiple smaller files 【发布时间】:2013-09-21 14:15:54 【问题描述】:我想在 rails 4 应用程序中拆分我的路线。对于 rails 3,这个问题已经回答了几次,例如:
How to split routes.rb into smaller files Splitting Routes File Into Multiple Files在 rails 4 + 如何控制路线加载顺序的正确方法是什么?
从rails 3问题建议:
application.rb
config.paths['config/routes'] = Dir["config/routes/*.rb"]
失败:
/Users/jordan/.rvm/gems/ruby-2.0.0-head@books/gems/railties-4.0.0/lib/rails/application/routes_reloader.rb:10:in `execute_if_updated 中的救援': Rails::Application::RoutesReloader#execute_if_updated 委托给 updater.execute_if_updated,但 updater 为 nil:
@route_sets=[#]> (运行时错误)
【问题讨论】:
【参考方案1】:这已于 2012 年 6 月从 Rails 4 中删除。5e7d6bba 恢复了较早的提交,删除了对加载多个外部路由文件作为 config.rb 的一部分的支持。
如需进一步阅读,请查看commit 上的 cmets。
【讨论】:
【参考方案2】:聚会有点晚了,但您可以在 Rails 4 中通过猴子修补您的 routes.rb 文件顶部的映射器来做到这一点。即:
# config/routes.rb
class ActionDispatch::Routing::Mapper
def draw(routes_name)
instance_eval(File.read(Rails.root.join("config/routes/#routes_name.rb")))
end
end
然后在 routes.rb 中使用draw
方法:
Rails.application.routes.draw do
draw :api
end
这需要 config/routes/api.rb 中的文件。
这里有examples of splitting the routes file 的稍微完整的解释。
【讨论】:
你推荐了猴子补丁,但没有警告猴子补丁可能对项目造成的坏事。 @yagooar,我在我的项目中使用它,它到底有什么问题?快速谷歌搜索没有提供任何“坏”的东西 我想这应该会阻止路线重新加载【参考方案3】:我是这样处理的:
# config/application.rb
config.autoload_paths << Rails.root.join('config/routes')
# config/routes.rb
Rails.application.routes.draw do
root to: 'home#index'
extend ApiRoutes
end
# config/routes/api_routes.rb
module ApiRoutes
def self.extended(router)
router.instance_exec do
namespace :api do
resources :tasks, only: [:index, :show]
end
end
end
end
在这里我添加了config/routes
目录来自动加载其中定义的模块。
这将确保在这些文件更改时重新加载路由。
使用extend
将这些模块包含到主文件中(它们将被自动加载,不需要它们)。
在self.extended
中使用instance_exec
在路由器的上下文中绘制路由。
【讨论】:
【参考方案4】:我不喜欢之前发布的解决方案——通过猴子补丁进行扩展——因为它们要么:
-
打破 OOP (
File.read
+ instance_eval
- cripes) 或
抑制可重用性:包括模块 - 你只能做一次 - 没关系,在第二次你明白模块包含实际上是执行一些代码的机制,cripes
我们不再是 2000 年代了,移动部分源文件和 File.read
-instance_eval
然后想知道发生了什么 - 或者将模块作为穷人的函数调用包含在内是不可接受的- 如果有任何选择。
我这样做了,注意它是可嵌套的:
scope :processing do
SomeModule::SomeDomain::Routes.call(self)
end
# and it's reusable:
scope :some_other_scope do
SomeModule::SomeDomain::Routes.call(self)
end
这种方法的好处是最终它只是简单的可执行 ruby 代码,您的 IDE 和其他程序员都可以移动并清楚地理解它。
你会在routes.rb
找到上面提到的一段代码你会看它,你会控制-点击它and what you'll find is what you expected:
module SomeModule::SomeDomain
class Routes
def self.call r
r.scope :some_scope do
r.match .....
end
end
end
这意味着这是干净的代码。
它也没有停留在 Rails 似乎长期强制执行的“面向函数的代码组织”中,而是允许您使用自己的路由树构建特定于域的结构,这应该是更可取的规范。
PS
我还使用了module,它使类嘎嘎声像一个函数 - 允许与 procs 组合等等 - 但这在这里并不是必需的,它只是给你说 SomeModule::SomeDomain::Routes[self]
的语法糖果
【讨论】:
以上是关于rails 4:将 routes.rb 拆分为多个较小的文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 rails 4 中重新加载路由 /config/routes/*?
ruby rails_routes_multiple_files.rb