すこし伝統があるRailsアプリケーションを修正しようとしました。
config/routes.rb
にすでに使っていないルーティングが残っていることに気がつきました。
対応するアクションメソッドの実装がないため、使っていないルーティングだと判断しました。
温かみのある手作業でチェックしても良いのですが、自動的に検出できそうな気もします。
ぐぐってもいい情報がみつけられませんでした。
同僚に相談したところ、
ruby - How to verify controller actions are defined for all routes in a rails application? - Stack Overflow
を教えてもらいました。
未解決ですが、回答によるとRails.application.routes
からルーティング情報が取得できるようです。
これを元にアクションメソッドが存在しないルーティングを見つけるスクリプトを作成しました。
bad_informations = Rails.application.routes.set.map { |r| r.defaults } .reject { |r| r[:controller].nil? } .reject { |r| r[:controller].include? '/' } .reduce([]) do |bad_informations, r| controller = r[:controller] + '_controller' action = r[:action] begin class_name = controller.singularize.camelcase if class_name.constantize.instance_methods.include?(action.to_sym) # p "#{class_name}クラスの#{action}メソッドはあります" else bad_informations << "#{class_name}クラスの#{action}メソッドはありません" end rescue NameError bad_informations << "#{class_name}クラスはありません" end bad_informations end .sort.uniq p *(bad_informations)
Railsの情報を参照するのでrails runner
から起動します。
例えば bin/rails runner hoge.rb
です。
次のような出力をします。
"AnnotationsControllerクラスのcreate_from_tgzメソッドはありません" "AnnotationsControllerクラスのcreate_project_annotations_rdfメソッドはありません" "AnnotationsControllerクラスのeditメソッドはありません" "AnnotationsControllerクラスのnewメソッドはありません" "AnnotationsControllerクラスのshowメソッドはありません" "AnnotationsControllerクラスのupdateメソッドはありません" "DocsControllerクラスのsearchメソッドはありません" "JobsControllerクラスのcreateメソッドはありません" "JobsControllerクラスのeditメソッドはありません" "JobsControllerクラスのnewメソッドはありません" "MessagesControllerクラスのcreateメソッドはありません" "MessagesControllerクラスのdestroyメソッドはありません" "MessagesControllerクラスのeditメソッドはありません" "MessagesControllerクラスのnewメソッドはありません" "MessagesControllerクラスのupdateメソッドはありません" "NoticesControllerクラスはありません" "ProjectsControllerクラスのcreate_from_tgzメソッドはありません" "ProjectsControllerクラスのdelete_reference_projectメソッドはありません" "ProjectsControllerクラスのselect_reference_projectメソッドはありません" "ProjectsControllerクラスのzip_uploadメソッドはありません" "SqlsControllerクラスのcreateメソッドはありません" "SqlsControllerクラスのdestroyメソッドはありません" "SqlsControllerクラスのeditメソッドはありません" "SqlsControllerクラスのnewメソッドはありません" "SqlsControllerクラスのshowメソッドはありません" "SqlsControllerクラスのupdateメソッドはありません" "UsersControllerクラスのcreateメソッドはありません" "UsersControllerクラスのdestroyメソッドはありません" "UsersControllerクラスのeditメソッドはありません" "UsersControllerクラスのnewメソッドはありません" "UsersControllerクラスのupdateメソッドはありません"
Railsのルート情報には次のようにrails/info/propertie
のようなルートが含まれています。
irb(main):001:0> Rails.application.routes.set.map { |a| a.defaults }.first => {:controller=>"rails/info", :action=>"properties"}
これらはアプリケーションのアクションメソッドと関係がありません。
雑に.reject { |r| r[:controller].include? '/' }
として、/
を含むコントローラーを除外しています。*1
追記
https://t.co/zyhUi6g3nB
— あおうさ (@bluerabbit777jp) June 11, 2022
これおすすめです
*1:元ネタのstackoverflowでは / を :: に置換しているので、その方がいいかもしれません。