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/*?

你必须弄乱 Rails 的“routes.rb”文件吗?

:就像在rails routes.rb中一样

ruby rails_routes_multiple_files.rb

有没有办法在 Ruby on Rails routes.rb 中定义没有“/new”的新操作路径?

(Starter。坚持这一点)生成了Rails项目:缺少config / routes.rb文件