動かざることバグの如し

近づきたいよ 君の理想に

Railsでルーティング一覧を生成してCSV出力する

環境

やりたいこと

Railsは基本的には規則に沿ったルーティングになるが、規模が大きくなってくるといろいろ管理が辛くなってくる。今回ちょっと別のアプリにRailsのURL一覧を読み込ませる必要があったのだが、流石に手動で書くのはキツかったのでCSV出力してみた

コード

bundle exec rails g task route csvとかで適当にタスクを作成

で以下追記

task csv: :environment do |t|
  class CSVFormatter
    def initialize
      @buffer= []
    end

    def result
      @buffer.join("\n")
    end

    def section_title(title)
    end

    def section(routes)
      routes.each do |r|
        @buffer << [r[:name], r[:verb], r[:path], r[:reqs]].join(",")
      end
    end

    def header(routes)
      @buffer << %w"Prefix Verb URI_Pattern Controller#Action".join(",")
    end

    def no_routes
      @buffer << ""
    end
  end
  require "action_dispatch/routing/inspector"
  all_routes = Rails.application.routes.routes
  inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
  puts inspector.format(CSVFormatter.new, ENV['CONTROLLER'])
end

あとは

rails route:csv

とすれば

Prefix,Verb,URI_Pattern,Controller#Action
root,GET,/,votes#index
votes,POST,/api/votes(.:format),votes#create
,GET,/votes(.:format),votes#index
vote,GET,/votes/:id(.:format),votes#show
test_iframes,GET,/iframes/test(.:format),iframes#test
iframes,GET,/iframes(.:format),iframes#index
rails_service_blob,GET,/rails/active_storage/blobs/:signed_id/*filename(.:format),active_storage/blobs#show
rails_blob_representation,GET,/rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format),active_storage/representations#show
rails_disk_service,GET,/rails/active_storage/disk/:encoded_key/*filename(.:format),active_storage/disk#show
update_rails_disk_service,PUT,/rails/active_storage/disk/:encoded_token(.:format),active_storage/disk#update
rails_direct_uploads,POST,/rails/active_storage/direct_uploads(.:format),active_storage/direct_uploads#create

といった感じに表示される

キモはやっぱりActionDispatch::Routing::RoutesInspectorだと思う。Railsではルーティングの表示をWEBブラウザ上での表示や、rake routes等によるCUI経由など複数に渡る。それらを出力のフォーマットを設定すればオリジナルのルーティング出力器が作れるってわけ。

このへんはrails5以降でかなり洗練された気がする