Ruby on Rails の ActiveRecord についてくる has_many
メソッドは、モデルクラス間の関連を宣言的に書けて大変便利だと思います。
自分でも同じように宣言的に書けるメソッドを定義したいと思ったことがある人は多いでしょう。
本記事では、このようなメソッドの定義方法について簡単に紹介したいと思います。
class Post < ActiveRecord::Base
# こんな風に関連を宣言的に書けて便利ですね。
# 本記事ではこのようなメソッドの定義方法を見て行きます。
has_many :comments
end
時間がない人向け
class Base
class << self
attr_accessor :_label
def label label
self._label = label
end
end
def to_s
"<#{self.object_id}@#{self.class._label}>"
end
end
class Conc < Base
label "とあるクラス"
end
puts Conc.new.to_s # <2939193@とあるクラス>
どのように定義するか
リファレンスによれば、クラス定義式の中では self
はそのクラスになります。
なお、通常(トップレベル)での self
は main オブジェクトです。
実験してみましょう。
puts self # main
class Hoge
puts self # Hoge
end
と、いうわけで、メソッドを定義してあげると、クラス定義式中でそのメソッドを使うことが可能となります。
class Hoge
def self.piyo
puts 47
end
piyo
end
引数をとって値を保存するにはクラス変数に保存してあげればよいでしょう。
class Hoge
def self.piyo val
@val = val # ここは @@val にしないでくださいね。
# ややこしいですが、Hogeのクラス変数は「Hoge というクラス」のインスタンス変数とほぼ同義だからです。
end
def self.fuga
@val || ''
end
piyo 'aaa'
end
puts Hoge.fuga # 'aaa'
モジュールにした場合は Module#include
が使えないことにご注意ください。特異クラスに対する Module#include
を実現するものとして Object#extend
がありますので、そちらを使います。
module M
def m1 val
@val = val
end
def m2
@val || ''
end
end
class C
extend M
m 'test'
end
puts C.m2 # 'test'