[開発] Pluggable Routing

各 /components//config/routes.rb にルーティングファイルを独立して記述する方法。ちょっと強引だができた。

# config/routes.rb

module WebJourney
  module Routing
    class ComponentRoutes
      def self.mapper=(mapper)
        @@mapper = mapper
      end

      def self.draw
        yield @@mapper
      end
    end
  end
end

ActionController::Routing::Routes.draw do |map|
  # 
  # ..(snip) ..
  # 

  # load all routing files from components
  WjComponent.find(:all).each do |component|
    path = File.join(RAILS_ROOT, "components", component.programatic_name, "config/routes.rb")
    if File.exists?(path)
      map.namespace("#{component.programatic_name}", :path_prefix =>"components") do |component_map|
        WebJourney::Routing::ComponentRoutes.mapper = component_map
        load path
      end
    end
  end
  map.root :controller => "wj_pages", :action => "show"
end

で、例えば、components/system/config/routes.rb に次のように書いておく。

WebJourney::Routing::ComponentRoutes.draw do |map|
  map.resource :user
end

すると、rake routes で、

                       system_user_index GET    /components/user                             {:action=>"index", :controller=>"system/user"}
             formatted_system_user_index GET    /components/user.:format                     {:action=>"index", :controller=>"system/user"}
                                         POST   /components/user                             {:action=>"create", :controller=>"system/user"}
                                         POST   /components/user.:format                     {:action=>"create", :controller=>"system/user"}
                         new_system_user GET    /components/user/new                         {:action=>"new", :controller=>"system/user"}
               formatted_new_system_user GET    /components/user/new.:format                 {:action=>"new", :controller=>"system/user"}
                        edit_system_user GET    /components/user/:id/edit                    {:action=>"edit", :controller=>"system/user"}
              formatted_edit_system_user GET    /components/user/:id/edit.:format            {:action=>"edit", :controller=>"system/user"}
                             system_user GET    /components/user/:id                         {:action=>"show", :controller=>"system/user"}
                   formatted_system_user GET    /components/user/:id.:format                 {:action=>"show", :controller=>"system/user"}
                                         PUT    /components/user/:id                         {:action=>"update", :controller=>"system/user"}
                                         PUT    /components/user/:id.:format                 {:action=>"update", :controller=>"system/user"}
                                         DELETE /components/user/:id                         {:action=>"destroy", :controller=>"system/user"}
                                         DELETE /components/user/:id.:format                 {:action=>"destroy", :controller=>"system/user"}
      

にでる。そりゃそうか。draw を誤魔化しつつ、loadしてるだけだし。

で、ふと思ったのは、そもそも、components/ ディレクトリは Rails 1.X 時代の名残をぜんぶ取っ払って、普通に1つのRails Applicationを置くようにすれば既存のRailsアプリのウィジェット化も楽になるんじゃないか?と思った次第。

なんかいろいろやることがでてきたが、これで完成すれば Ver 0.4 RESTful Implementation and Rails 2.0 Support でだせるな。目標 2/22。既存のウィジェットの書き直しが結構入りそうだけど、Modelはいじらなくても大丈夫か。