LoginSignup
0
0

More than 5 years have passed since last update.

(Rails)Controller#statusをmodule化するとActionNotFoundが発生する

Last updated at Posted at 2016-11-16

概要

概要というかタイトルそのまま。

Railsの Controllerstatus というアクションを使うときは注意が必要。

普通に Controller 内で status アクションを定義している分には問題ないが、
status アクションを module にして使おうとすると ActionNotFound のエラーが発生する。

詳細

例えば以下のような Controller がある。

app/controllers/sample_controller.rb
class SampleController < ApplicationController
  def index
    # code
  end

  def status
    # code
  end
end

これにルーティングを設定しておけば
それぞれのアクションが実行される。

しかしこの Controller を以下のように module 化して Controllerinclude する。

app/controllers/sample_controller.rb
class SampleController < ApplicationController
  include SampleModule
end
app/controllers/concerns/sample_module.rb
module SampleModule
  extend ActiveSupport::Concern

  def index
    # code
  end

  def status
    # code
  end
end

こうすると index アクションは実行されるが status アクションは AbstractController::ActionNotFound が発生する。

怖い。

対応策

とりあえず暫定的な対応策は以下の2点

  • status というアクション名を変更する
  • def statusActiveSupport::Concernincludedblock で囲む

こんな感じ。

app/controllers/concerns/sample_module.rb
module SampleModule
  extend ActiveSupport::Concern

  def index
    # code
  end

  included do
    def status
      # code
    end
  end
end

原因?

下記の記事を参考

簡単に説明するとActionControllermodule の中に Metal という class が定義されている。

そしてこの中に status というメソッドが定義されている。

どうやらこいつのせいで上手く moduledef status が実行できなくなってしまっているらしい。

うーん、普通後から include された module#method が実行されると思うんだけど……。
Controller が命名規則で action を実行する手順のどっかが悪いのかなと思っている。

後書き

とりあえず status なんてアクションはよく使う名前だと思うので困った。

Controlleractionmodule 化するのはやりすぎって意見もあるんでしょうが、
もっといい解決方法があったら教えてください。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0