概要
概要というかタイトルそのまま。
Railsの Controller
で status
というアクションを使うときは注意が必要。
普通に Controller
内で status
アクションを定義している分には問題ないが、
status
アクションを module
にして使おうとすると ActionNotFound
のエラーが発生する。
詳細
例えば以下のような Controller
がある。
class SampleController < ApplicationController
def index
# code
end
def status
# code
end
end
これにルーティングを設定しておけば
それぞれのアクションが実行される。
しかしこの Controller
を以下のように module
化して Controller
に include
する。
class SampleController < ApplicationController
include SampleModule
end
module SampleModule
extend ActiveSupport::Concern
def index
# code
end
def status
# code
end
end
こうすると index
アクションは実行されるが status
アクションは AbstractController::ActionNotFound
が発生する。
怖い。
対応策
とりあえず暫定的な対応策は以下の2点
-
status
というアクション名を変更する -
def status
をActiveSupport::Concern
のincluded
のblock
で囲む
こんな感じ。
module SampleModule
extend ActiveSupport::Concern
def index
# code
end
included do
def status
# code
end
end
end
原因?
下記の記事を参考
簡単に説明するとActionController
の module
の中に Metal
という class
が定義されている。
そしてこの中に status
というメソッドが定義されている。
どうやらこいつのせいで上手く module
の def status
が実行できなくなってしまっているらしい。
うーん、普通後から include
された module#method
が実行されると思うんだけど……。
Controller
が命名規則で action
を実行する手順のどっかが悪いのかなと思っている。
後書き
とりあえず status
なんてアクションはよく使う名前だと思うので困った。
Controller
の action
を module
化するのはやりすぎって意見もあるんでしょうが、
もっといい解決方法があったら教えてください。