【问题标题】:rails 4: split routes.rb into multiple smaller filesrails 4:将 routes.rb 拆分为多个较小的文件
【发布时间】:2013-09-21 14:15:54
【问题描述】:

我想在 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_if_updated 中的救援': Rails::Application::RoutesReloader#execute_if_updated 委托给 updater.execute_if_updated,但 updater 为 nil:

@route_sets=[#]> (运行时错误)

【问题讨论】:

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


    【解决方案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】:

        我不喜欢之前发布的解决方案——通过猴子补丁进行扩展——因为它们要么:

        1. 打破 OOP (File.read + instance_eval - cripes) 或
        2. 抑制可重用性:包括模块 - 你只能做一次 - 没关系,在第二次你明白模块包含实际上是执行一些代码的机制,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] 的语法糖果

        【讨论】:

          猜你喜欢
          • 2012-02-13
          • 1970-01-01
          • 1970-01-01
          • 2016-06-07
          • 2017-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多