以前から気になっていたconcernsディレクトリが何なのか調べてみた。
app/controllers/concerns/
app/models/concerns/
先に結論。共通化に役立つ。必要なController(Modelも)からだけ呼べるので、影響範囲を限定できる。TaskとControllerの共通化が容易になる。
とりあえず書いてみる
app/controllers/concerns/foo.rb を作成
module Foo extend ActiveSupport::Concern included do def bar 'baz' end end end
app/controllers/top_controller.rb にincludeとbarを追加
class TopController < ApplicationController include Foo
def index p "bar: #{bar}"
% rails s -> http://127.0.0.1:3000/ "bar: baz"
考察
複数のControllerでメソッドを共通化したい時の選択肢
1. 継承元のApplicationControllerに移す
-> 肥大化するのと使わないControllerからも参照可能なのが課題
2. ApplicationControllerの前に継承元のControllerを追加する
-> 継承が複雑になるのが課題
3. Serviceを導入する
-> 目的が明確な場合はとても良いけど、Service間での共通化はどうする?
4. Concernを作ってincludeする
-> 必要なものだけincludeできるのが良さそう!
Taskから呼び出せそう
lib/tasks/user.rake にもincludeとbarを追加
namespace :user do desc '削除予定日時を過ぎたユーザーのアカウントを削除' task(:destroy, [:dry_run] => :environment) do |_, args| include Foo p "bar: #{bar}"
% rails user:destroy "bar: baz"
考察
継承がないTaskでもConcernをincludeするだけで、Controllerのメソッドを呼び出せる。バッチとフロントの処理の共通化が簡単!
Serviceでも可能だが、new(初期化)してから、目的に応じてメソッドを使い分けるので、難しくないけどお手軽でもない。
あと、標準でディレクトリが用意されていないので、使うべきか悩む。
参考
Concernの参考記事
Service導入の参考記事
“Concernが便利かもと思った話” に対して1件のコメントがあります。