Nic Lin's Blog

喜歡在地上滾的工程師

拆分你的 routes.rb,使他更好維護及整理

How to split routes.rb into smaller parts?

在 Rails 開發上, route(路由)就像總機小姐,可以清楚的幫你承接到業務承辦人員, Routing 就是替你的頁面指路,經過 Controller Action 後呈現你想要的頁面。

在 Ruby on Rails 開發應用上, config/routes 這隻檔案會隨著程式碼日積月累的成長而變得更肥大,這會使開發人員更難以維護,也會在搜尋具體路徑變得越來越困難,當使用者頁面、登陸頁、後台、API…等路由全都攪和在一起,那是非常惱人的事情。

參考如下:

ActionController::Routing::Routes.draw do
  root to: "home#index"
  get "/about
  get "/login" => "application#login"

  namespace :api do
    #nested resources
  end

  namespace :admin do
    #nested resources
  end

  namespace :messages do
    #nested resources
  end

  namespace :orders do
    #nested resources
  end
end

Rails 3

如果你的應用程序在 Rails 版本 3,可以嘗試以下的解法

config.paths["config/routes"] += Dir[Rails.root.join('config/routes/*.rb’)]

想控制的更清楚一些,可以指定引入的檔名

config.paths["config/routes"] = %w(
      config/routes/messages.rb
      config/routes/orders.rb
      config/routes/admin.rb
      config/routes/api.rb
      config/routes.rb
    ).map { |relative_path| Rails.root.join(relative_path) }

Raisl 4

不過在 Rails 4 之後,如果你利用了上述的寫法嘗試解決,會拋出異常(throw an exception),因為在 Rails 4 之後的版本裡, Rails::Engine 並不存在這個 key ['config/routes']

那麼最佳的解法,是可以共存 Rails 3 & 4 & 5的

看以下範例 code

YourApplication::Application.routes.draw do

def draw(routes_name)
    instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
end

  draw :messages
  draw :orders
  draw :api
  draw :admin

  root to: "home#index"
  get "/about
  get "/login" => "application#login" 

end

這樣你就可以在 config/routes/api.rb 只放關於 api 的 routes

  namespace :api do
    #nested resources
  end

可以只在 config/routes/admin.rb 只放關於後台權限相關的 routes

  namespace :admin do
    #nested resources
  end
project
└─── config
│   │   routes.rb
│   │
│   └─── routes
│       │   api.rb
│       │   admin.rb
│       │   ...

是不是看起來好多了?

將同一種類型的路由整理起像 component 來使用,除了好維護,也容易進行找查相關路徑。

其原理是 ActionDispatch::Routing 允許我們在裡面加入一個新的方法來使用,這有助於我們加載相關路徑。

參考資源: How to split routes.rb into smaller parts?

comments powered by Disqus