rails 4:将routes.rb拆分为多个较小的文件

时间:2013-09-17 08:23:22

标签: split routes ruby-on-rails-4

我想在rails 4应用程序中拆分路由。对于rails 3,问题已被回答了几次:

在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 in execute_if_updated':   Rails :: Application :: RoutesReloader#execute_if_updated委托给   updater.execute_if_updated,但updater为nil:

           

@route_sets = [#]>   (RuntimeError)

4 个答案:

答案 0 :(得分:18)

我这样管理:

# 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将这些模块包含在主文件中(它们将被自动加载,无需使用它们)。

instance_exec内使用self.extended在路由器的上下文中绘制路由。

答案 1 :(得分:9)

派对有点晚了,但你可以在Rails 4中通过猴子修补你的routes.rb文件顶部的mapper来做到这一点。即:

draw

然后使用routes.rb中的Rails.application.routes.draw do draw :api end 方法:

Workbooks

这将指向config / routes / api.rb中的文件。

这里用examples of splitting the routes file稍微更全面的解释。

答案 2 :(得分:4)

这已于2012年6月从Rails 4中删除。5e7d6bba恢复了先前的提交,删除了对作为config.rb的一部分加载多个外部路由文件的支持。

如需进一步阅读,请查看有关此commit的评论。

答案 3 :(得分:0)

我不喜欢以前发布的解决方案-除了猴子修补之外的扩展-因为它们之一:

  1. 打破OOP(File.read + instance_eval-薄饼)或
  2. 禁止可重用性:包括模块-您只能执行一次-没关系,第二天您了解到模块包含实际上是执行一些代码(即绉)的机制

我们已经不在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

这种方法的好处是,最终,它只是简单的可执行红宝石代码,您的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和更多内容进行合成-但这在这里并不是必需的,它只是给您说{ {1}}