LoginSignup
100
96

More than 5 years have passed since last update.

ActiveSupport::Concern と、Module#concerning

Posted at

concern

関心事、関連、利害関係 など

Rails 4.0 -> concerns ディレクトリ

Mix-in 用のモジュールを置くディレクトリ concerns が定義された

  • app/models/concerns
  • app/controllers/concerns

それぞれ、モデル、コントローラーの Mix-in 用のモジュールを置く

何が得なの?

  • models や、controllersでしか使わない module は、concerns ディレクトリに置くというルールができた
  • lib になんでも置いちゃう病が少し良くなる
  • lib に色々置かれてて、何に使うコードなのかよくわからないのが色々あるという状況が少し良くなる
  • もしくは、勝手に独自のディレクトリに置かれるということが無くなった

ActiveSupport::Concern

Mix-in するモジュール側で、ActiveSupport の機能を使いたい場合は、
extend ActiveSupport::Concern を呼ぶこと

実装例

app/model/member.rb
class Member
  include Human
end
app/model/concerns/human.rb
module Human
  extend ActiveSupport::Concern

  included do
    attr_accessor :name
    def self.default_name
      "太郎"
    end

    def default_name?
      name == self.class.default_name
    end
  end
end

実行結果

irb(main):001:0> m = Member.new
=> #<Member:0x007f92cfae15c8>
irb(main):002:0> m.name = "二郎"
=> "二郎"
irb(main):003:0> m.default_name?
=> false
irb(main):004:0> m.name = "太郎"
=> "太郎"
irb(main):005:0> m.default_name?
=> true

と、まぁこんな感じで、複数の model で使いたい機能を module 化したい時に、手軽に扱う事ができる

Rails 4.1 -> Module#concerning

Rails 4.1 では新たに Module#concerning が追加された
これは、Concern を 1つのファイル内でやりたいときに使えるっぽいのだが...?

実装例

app/model/member.rb
class Member
  include Human
end

class Member
  concerning :Human do
    included do
      attr_accessor :name
      def self.default_name
        "太郎"
      end

      def default_name?
        name == self.class.default_name
      end
    end
  end
end

こんな風に、concern ディレクトリをつかわずに、concerning ができる

使い道は?

多分だけど、1つのクラスの中で意味合いが異なる処理がある場合に、それを分割することで、感心事を分ける為の仕組みの様子
当然ながら複数のクラスで同一の処理を行ないたい場合は、4.0 の concerns ディレクトリの仕組みを使うべき

参考

100
96
1

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
100
96