Rubyのinclude,extend,prepend,Concernの使い方メモ
なんとなく理解が怪しかったので復習をかねて。
includeだけでクラスメソッドとインスタンスメソッドを同時に追加する
module MyModule def self.included(base) base.extend(ClassMethods) end module ClassMethods def hogehoge puts 'hogehoge!' end end def fugafuga puts 'fugafuga' end end class TargetModel include MyModule # 略 end
・includeは、モジュールのメソッドをインスタンスメソッドとして追加する。
・extendは、レシーバ自身に対してメソッドを追加する。
クラス.extend モジュール の場合はクラスメソッドとして
インスタンス.extend モジュール の場合はインスタンスメソッドとして追加される。
・モジュールにincludedを定義しておくと、includeされたときに呼び出される。
引数はincludeを行ったクラスやモジュール。
ActiveSupport::Concernを使う場合
require 'active_support/concern' module ConsernModule extend ActiveSupport::Concern # インスタンスメソッドとして使える def hogehoge # do something end # アクセサやscopeの定義はincludedの中で行う included do attr_accessor :fugafuga scope :favorites, -> { where(favirite_flag: true) } end # クラスメソッドの定義はclass_methodsの中で行う class_methods do def piyopiyo # do something end end # privateインスタンスメソッド private def wiblewible # do something end end class TargetModel include ConsernModule # 略 end
prependを使う
module TargetModelPatch def self.prepended(base) base.extend(ClassMethods) base.has_many :childrens base.scope :without_deleted, { where(deleted_at: nil) } end module ClassMethods def hogehoge puts 'hogehoge!' end end def fugafuga puts 'fugafuga' end end TargetModel.prepend TargetModelPatch
includeと基本的な動きは同じだけど、同じメソッドがあった場合はモジュール側のメソッドで上書きになる。
これは、prependが継承チェインの「先頭」にモジュールを差し込むため。
なお、includeの場合は取り込んだクラス側のメソッドが優先になる。
※参考にさせていただきました。
いつも忘れるRubyの include, prepend, extend の意味。そしてActiveSupport::Concernについても。 - Qiita
www.techscore.com