LoginSignup
12
11

More than 5 years have passed since last update.

Railsでメタプロ的にクラスマクロを作成する

Posted at

別にRailsではなくても純粋なRubyでも基本的には同じ。

module Fuga
  def self.included base
    base.extend ClassMethods
  end

  module ClassMethods
    def hello
      puts 'Hello!'
    end
  end
end

Fugamoduleがインクルードされた時にClassMethodsで定義さていているメソッドが使えるようになる。

下記のようにすれば、インスタンスメソッドも追加出来ます。

module Fuga
  def self.included base
    base.extend ClassMethods
  end

  module ClassMethods
    def hello
      puts 'Hello!'
    end
  end

  #以下追加
  def bar
   puts "bar"
  end
end

このFugamoduleを任意のClassにincludeすれば、helloがクラスマクロとして使用できるようになります。

class Bar
  include Fuga
  hello
end

これはextendを使って書き換えることができます。

module Fuga
  def hello
    puts 'Hello!'
  end
end

class Bar
  extend Fuga
  hello
end

extendで呼ぶ出すとクラスメソッドとして定義されます。

ActiveSupport::Concernをextendしてくると、def self.included endの部分を省略できます。

module Fuga
  extend ActiveSupport::Concern

  module ClassMethods
    def hello
      puts 'Hello!'
    end
  end
end

これで任意のクラスでFugaをincludeすれば、helloがクラスマクロとして使えるようになります。

ここからがRailsの話し。

module AddDeleted
  extend ActiveSupport::Concern

  module ClassMethods
    def add_deleted
      attr_accessor: :deleted
    end
  end
end

class ActiveRecord::Base
  include AddDeleted
end

class Book < ActiveRecord::Base
 add_deleted
end

上記のように、AddDelatedmoduleを作成して、ActiveRecord::Baseを再オープンしてAddDelatedをincludeするとActiveRecord::Baseを継承するクラスでadd_deletedが使えるようになります。

add_deletedが呼ばれたクラスでは、attr_accessordeletedが追加されます。

参考

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11