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 ディレクトリの仕組みを使うべき