RailsのActiveSupport:Concernの役割
Railsで共通部分をmoduleに切り出し、Concernを使う機会があったが、そもそもRubyであまりmoduleを使ったことがなく、Concermが通常のmodule機能と比べてどう特殊なのかわからなかった。この機会におさらいしてみる。
Rubyのmoduleの使い方
まずはRails以前の、Rubyでのmoduleについて。moduleに定義した変数は、moduleの名前とともに指定すれば使うことができる。
mod Constant NUMBER = 5 end class Hoge a = Constant::NUMBER # 5 end
しかし、メソッドはこのやり方では使えない。moduleで定義したメソッドを使うためには、includeをする必要がある。includeとは、そのmodule内で定義されたメソッドや変数を引き継ぐことであり、mix-inとして使うことができる。
mod Constant def plus_one(num) num + 1 end end class Hoge include Constant a = plus_one(4) # 5 end
includeされたメソッドは、そのクラスのインスタンスメソッドとして使うことができる。
Concernでクラスメソッドを楽に使う
ただし、上記のincludeができるのはインスタンスメソッドのみであり、クラスメソッドをmoduleで定義して外から使うためには複雑な記法を使わなければならない。とはいえRailsの場合、データ取得の際などにクラスメソッドを使う機会が多い。
そこでConcernを使うことで、クラスメソッドをmodule化しやすくなる。
module M extend ActiveSupport::Concern included do scope :disabled, -> { where(disabled: true) } end class_methods do ... end end
上記のscopeは当然クラスメソッドだが、 included do ... end
の中に書くだけになっている。あとはこのmoduleを対象クラスにincludeすれば、そのクラス内で定義したscopeと同じように、 :disabled
のスコープを使えるようになる。
Railsは様々な独自記法があると聞いていたが、こんな形であるとは知らなかった。Railsしか知らないとどれが独自の書き方がわからなさそうなので、Rubyの文法と比べる習慣をつけていきたい。