about 4 years ago

Module
Module的好處就是可以選擇性的引用Module內的方法,不會讓Module內的變數或是Method與其他Class互相影響

引用Module的方式有以下兩種
第一是可以在Class內include Module

class Include < Example
    include module
end

使用include的方式可以讓module的method在class底下被取用
所以我們就可以使用這樣的方法:

user.module_method

另外一個引用方式是Extend
Extend的用法是讓Class可以直接取用Module內的Method

class Extend < Example
    extend module
end

所以這樣這個時候我們就可以使用這樣的寫法:

Extend.module_method

進階做法

我們可以針對某個特定的object做module extend,例如

image = Image.new
image.extend(module)
image.module_method  #可以成功取用method


image2 = Image.new
image2.module_method #失敗,因為是不同的object

self.included hook

在module內定義ClassMethods的Module
再def delf.included 就可以省去Class中的extend LibraryUtils::ClassMethods
如此一來ClassMethods就可以被引用的class直接使用
*ClassMethods可以取任何名字,但rails convention是ClassMethods,才可以使用ActiveSupport::Concern

module LibraryUtils
  def self.included(base)
    base.extend(ClassMethods)
  end
  def add_game(game)
  end
  def remove_game(game)
  end

  module ClassMethods
    def search_by_game_name(name)
    end
  end
end

class AtariLibrary
  include LibraryUtils
  # extend LibraryUtils::ClassMethods   用了self.included後就可省略

end

ActiveSupport::Concern

遵循rails convention,引入ActiveSupport::Concern就可以達到上面self.included hook的效果

require "active_support/concern"
module LibraryUtils
  extend ActiveSupport::Concern
  def add_game(game)
  end

  def remove_game(game)
  end

  module ClassMethods
    def search_by_game_name(name)
    end
  end
end

ActiveSupport::Concern進階用法

module LibraryLoader

  extend ActiveSupport::Concern

  module ClassMethods
    def load_game_list
    end
  end
end

module LibraryUtils
  extend ActiveSupport::Concern
  include LibraryLoader
  included do
    load_game_list
  end
end

class AtariLibrary
  include LibraryUtils
end

← [Rails Gem]Ransack-搜尋功能 [Rails 高級新手系列] 關於MVC →
 
comments powered by Disqus