🕺

親クラスの同名メソッドを呼ぶsuperのオシャレな使い方(Ruby on Rails)

2024/06/04に公開

先日、rubyのsuperメソッドについて面白オシャレな使い方をしているコードを発見しました。
ググって見ても同様の使い方が全然見つからなかったので、
これを記事にすれば少しは世のためになると拡大解釈して投稿します!😇

そもそもsuperって何?

という方は、公式のrubyリファレンスだったり、
このへんの分かりやすい記事を見て出直してきて下さい。
https://qiita.com/mao-0901/items/906587ad9c4108d70b62
https://zenn.dev/kingdom0927/articles/20899ba71b7c08

私が目にしたオシャレな使い方

※一部コードを改変

models/order.rb
Order < HogeHoge::Base01
  def channel
    Channel.find(super);
  end
end

上記のsuperメソッドについてです。
親クラス(ここではHogeHoge::Base01クラス)のchannelメソッドを呼び出しているはずなのですが、

親クラスには、

models/hoge_hoge/base01.rb
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