delegate
delegate :foo, to: :something
こう書くことで、メソッドが、somethingメソッドにチェーンしたsomething.foo(something.メソッド名相当のもの)として動くようになります。他にも、to: :@instance_varとすればインスタンス変数へ、to: :CONSTANTとすれば定数につなげることができます。
例 UserモデルとProfileモデルが1対1の関係。ユーザー名はProfileモデルに保存されてる状況で、普通に名前を取り出そうとすると@user.profile.nameとなる。
class User < ApplicationRecord
has_one :profile
delegate :name, to: :profile
end
とすると
@user.name
で名前にアクセスできるようになる。
class User < ApplicationRecord
has_one :profile
delegate :name, to: :profile, prefix: true
end
とすると
@user.profile_name
で名前にアクセスできるようになる。
###Userクラスに nameメソッドを定義するとします。 以下のようなコードになるでしょう。
class User < ApplicationRecord
has_one :profile
def name
profile.name
end
end
これでも良いんですが、もっと簡潔に書く方法が delegateです。
@user.nameと呼び出すことが下記の書き方でも実現できます。
class User < ApplicationRecord
has_one :profile
delegate :name, to: :profile
end
より明示的かつ、短く書くことができました。
インスタンス変数や定数へもアクセスが可能
delegateする対象ですが、インスタンス変数へアクセスすることも可能です。
delegate to:@user
また、定数を参照することも可能。 定数はそのままクラスメソッドのように呼び出せるのであまり使うケースは少なそうに思います。
delegate to: :NUMBER
オプションとして、prefixをつけることも可能です。
delegate to: :method_name, prefix: :aaa
上記のように書くと、メソッドを呼び出すときに以下のように呼び出すことができます。
@instance.aaa_method_name