親クラスの同名メソッドを呼ぶsuperのオシャレな使い方(Ruby on Rails)
先日、rubyのsuperメソッドについて面白オシャレな使い方をしているコードを発見しました。
ググって見ても同様の使い方が全然見つからなかったので、
これを記事にすれば少しは世のためになると拡大解釈して投稿します!😇
そもそもsuperって何?
という方は、公式のrubyリファレンスだったり、
このへんの分かりやすい記事を見て出直してきて下さい。
私が目にしたオシャレな使い方
※一部コードを改変
Order < HogeHoge::Base01
def channel
Channel.find(super);
end
end
上記のsuperメソッドについてです。
親クラス(ここではHogeHoge::Base01クラス)のchannelメソッドを呼び出しているはずなのですが、
親クラスには、
class HogeHoge::Base01 < ActiveRecord::Base
この中にchannelメソッドがない😨
end
という感じで、親クラスにchannelメソッドがありませんでした。
binding.pryで調べると、superの記載通りchannelメソッドが呼ばれているため、
Channel.find(super) → Channel.find(self.channel)
となっており、
Orderモデルのカラム名にあるchannelが呼ばれていました。
なぜ、カラム名のchannelをsuperが呼んでくれるのか🤔
私はこれがすぐに分かりませんでした…
ActiveRecordをきちんと理解している方なら、すでに気が付いているのかもしれませんが、
class HogeHoge::Base01 < ActiveRecord::Base
この部分で、HogeHoge::Base01は、ActiveRecord::Baseを継承しているから、
カラムをメソッドとして使えるchannelを持っており、
更に、
Order < HogeHoge::Base01 という関係なので、
superは、channelを呼んでくれていました😲
解釈が合っているのか確認のため、ソースコードのファイル名と行番号を調べてくれる
source_locationを使ったところ、
Order.instance_method(:channel).source_location
=> ["/tools/app/models/order.rb", 1187]
やはり、superがOrderモデルのchannelカラムを読んでいました。
(1187行は該当箇所)
superとActiveRecordの合わせ技で、
「親クラスのファイルにソースコード上、定義されていない同名メソッドが呼べる」
というオシャレな使い方でした!✨
良く使われる表現なのかどうか分かりませんが、
これを読んでsuperやActive Recordの理解が深まった方がいらっしゃれば幸いです。
ここまで読んで頂きありがとうございました🙇
分かりにくい所があれば、ぜひ教えて下さい!
Discussion