おかあさんといっしょを娘が見るので、毎朝のテレビチャンネルはEテレです。
さてrailsでapp/model/concerns以下のモジュールを勝手にapp/modelにincludeしたいと考えました。
命名規則でファイルを拾って、includeすることにします。
例えば以下のファイル名をつけた場合に
app/model/user.rb
app/model/user auto load _concern.rb
userクラスに自動でuser auto load _concern.rbの内容がincludeされる感じです。
config/initializerに置きます。
1
2
3
4
5
6
7
8
9
10
11
12
| %w(models).each do |elem|
Pathname.glob(Rails.root.join("app", elem, "concerns", "*")).each do |file|
if file.file?
file.basename.to_s.scan(/(.*)(_auto_load_concern.rb)$/) do |class_name|
if class_name.present?
model = class_name[0].classify.constantize
model.class_eval { include file.basename(".rb").to_s.classify.constantize }
end
end
end
end
end
|
でもこのプロジェクトにはmodelクラスを拡張するプログラムがlib下にあります。
それを読み込まない限りはmodelを参照するとエラーになるようになっています(上記class _name[0].classify.constantizeでエラーとなる)
そこでlib以下のそのプログラム群を読み込んだ後に読み込むようにしたいと思います。
まず先ほどのコードを以下のようにActiveSupport.on _loadで囲みます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| ActiveSupport.on_load(:hoge) do
%w(models).each do |elem|
Pathname.glob(Rails.root.join("app", elem, "concerns", "*")).each do |file|
if file.file?
file.basename.to_s.scan(/(.*)(_auto_load_concern.rb)$/) do |class_name|
if class_name.present?
model = class_name[0].classify.constantize
model.class_eval { include file.basename(".rb").to_s.classify.constantize }
end
end
end
end
end
end
|
lib下のプログラム群で処理が終わった後に以下を差し込みます。
1
| ActiveSupport.run_load_hooks :hoge
|
そうするとrun load hooksが呼ばれたタイミングでhogeがついていてるActiveSupport.on _loadのブロック処理が開始されます。