Link Search Menu Expand Document

Part 2: 關於 Model

10. 善用 Module 抽取相關代碼

情境:如果將代碼從 Controller 重構到 Model 做得不錯了,接下來如何進一步重構 Model 代碼?

重構前:在 Model 中有一些高度相關的代碼,希望能夠更清楚他們是一起的,或是希望能在不同 Model 中也能重復使用。

class User < ActiveRecord::Base

  validates_presence_of :cellphone
  before_save :parse_cellphone

  def parse_cellphone
    # do something
  end

  def self.foobar
    # do something
  end

end

重構後:善用 Ruby 的 module 語法,可以將這些相關代碼抽取出來,放在 app/models/concerns 目錄下,包括 model 的 validates 宣告、回呼宣告、關聯宣告、物件方法、類方法等等都可抽取出來。

module HasCellphone

  def self.included(base)
    base.validates_presence_of :cellphone
    base.before_save :parse_cellphone
    base.extend ClassMethods
  end

  def parse_cellphone
    # do something
  end

  module ClassMethods
    def foobar
      # do something
    end
  end

end

或是使用 Rails ActiveSupport::Concern 語法,可以更簡潔一點:

module HasCellphone
  extend ActiveSupport::Concern

  included do
    validates_presence_of :cellphone
    before_save :parse_cellphone
  end

  def parse_cellphone
    # do something
  end

  class_methods do
    def foobar
      # do something
    end
  end

end

最後在 model 裡面 include 即可。

class User < ActiveRecord::Base
  include HasCellphone
end

其他 model 也可以沿用這段代碼,只要 include 即可:

class Contact < ActiveRecord::Base
  include HasCellphone
end

這一招其實 controller 也可以用,在 rails 中 app/controllers/concerns 目錄就是拿來放 controller 的 module 檔案。


Copyright © 2010-2021 Wen-Tien Chang All Rights Reserved.