JT's Blog

Do the right things and do the things right.

Rails Module::Concerning and ActiveSupport::Concern

| Comments

Module#concerning

Rails 4.1 新增的功能,如果module 內容不多,但又非得新增一個module,或許可以考慮用concerning 的方式

一般使用mixin 使用方式

1
2
3
4
5
6
7
8
9
# app/models/article.rb
class Article < ActiveRecord::Base
  include Tagging
end

# app/models/concerns/tagging.rb
module Tagging
 # ...
end

使用concerning

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Article < ActiveRecord::Base
  # 基本:建立一般的 instance method
  concerning :Tagging do
    def news do
      # ...
    end
  end
  # 進階1:加入included (include 時執行)
  concerning :Scope do
    included di
      scope :published, -> { where(state: 'published') }
    end
  end
  # 進階2:加入class method
  concerning :Search do
    class_methods do
      def published do
        # ...
      end
    end
  end
end

Reference

ActiveSupport::Concern

  • 將共用的邏輯寫到module 並用mixin 的方式,如此可以集中管理
  • 讓module 的相依性降低(低耦合),方便管理
  • 命名以able结尾

一般module 要mixin 到class 要使用included

1
2
3
4
5
6
7
8
9
10
11
12
module M
  def self.included(base)
    base.extend ClassMethods
    base.class_eval do
      scope :disabled, -> { where(disabled: true)}
    end
  end

  module ClassMethods
    # ...
  end
end

如果使用ActiveSupport::Concern module 就可以改寫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require 'active_support/concern'

module M
  extend ActiveSupport::Concern

  # 在include 的時執行
  # 加入 scope 或 attr_accessor
  included do
    scope :disabled, -> { where(disabled: true)}
  end

  # 定義class methods
  class_methods do
    # ...
  end

  # 除了上面兩個區塊外,都屬於 instance methods
end

Reference

Comments