瀬宮の球拾いブログ

エンジニアだったはずが、みんなにヘイストかける方がチームに貢献できた男のブログ

moduleに skip_before_action を書いたら undefined method 'skip_before_action'

継承元のControllerで宣言されているbefore_actionを、継承先でskipさせたい。
かつ、skipさせたいクラスは複数あるので一つのhelperにまとめることにした。
そのために以下のコードを書いた。

module Api::Concerns::SkipAclHelper
 skip_before_action :has_allowed_acl?
end

include Api::Concerns::SkipAclHelper

したところ undefined method 'skip_before_action'

[原因]
moduleを読み込んだ段階で、Controllerに定義されるべきskip_before_actionクラスメソッドが書いてあったので「そんなん知らんわ」となった。
であるのでActionController::Baseを継承したクラスの中にskip_before_actionは書くべき。
しかしmoduleにActionController::Baseを継承させることはできない。
[対策]
include先では継承されているので、継承先で展開されるように以下のように書いた

module Api::Concerns::SkipAclCheckable
 extend ActiveSupport::Concern

 included do
  skip_before_action :has_allowed_acl?
 end
end

  includedは ActiveSupport::Concern の中で定義されているので ActiveSupport::Concern をextendする。
これで動いた。