🧖‍♂️

【Rails】モデル内に謎の単語があった?

2023/02/03に公開

Railsを用いた実務で以下のようなコードに出会いました(実際よりはかなり省略・修正しています)。

models/human.rb
class Human < ActiveRecord::Base
 #男かどうかを判別するメソッド manが1ならtrueを返すインスタンスメソッド
 def man?
  man == 1
 end
end

man?というインスタンスメソッドで男かどうかを判定するということはわかりました。ただこの中にあるmanがどこから来るのかが初めはわかりませんでした。どこかに定義されているのかなとも思ってファイル内を検索しましたが、どこにもmanはありませんでした。
今回の記事ではこのmanがどこから来たかを解説していきます。Railsのモデルのファイル内でよくわからない単語に出会ってしまった時に使える知識の1つになるかと思います!

結論

先に結論を述べたいと思います。Humanモデルに対応したDB(データベース)のテーブルにmanというカラムがあり、先ほどのmanの値はインスタンスのmanカラムのパラメーターを取り出しているということでした。

では、なぜそうなるのかを解説していきたいと思います。

self

まず、先ほどのコードは実はselfというものが省略されており、実際は以下コードのようになります。

class Human < ActiveRecord::Base
 def man?
  self.man == 1
 end
end

このselfはメソッドの実行主体を指すそうです。実行主体というと少し難しい気がしますが、結局そのメソッドを実行するのは誰?ということです。なので、インスタンスメソッド内のselfの実行主体はインスタンスということになります!

selfについては以下記事が非常に参考になりました。
参考:selfキーワードとメソッド呼び出し

このselfは省略が可能なので、selfの存在を知らずにコードを見たら何これ?となりました。

ただし以下リンクのようにselfを省略できない場合もあるみたいってことは覚えておいていただければと思います。
参考:rubyでselfを省略できる時、できない時

Railsでhumanというモデルに対応したテーブルにmanというカラムがある時、取得してきたインスタンスのmanパラメーターを取得したい時には以下のように実行できることはご存知でしょう。

@human = Human.find(1) #DBから取得したインスタンスデータを代入
#→小栗旬のレコード
@human.man #インスタンスのmanカラムのパラメーター
#→1


今回はselfがインスタンスとなることがわかったので、結局上記と同じことをしているということがわかりました。

この記事で言いたいことは大体伝え終わったのですが、参考として今回のman?メソッドが使われる時の例として以下のコードを記載します。
仮に上の表のようなデータだとすると小栗旬の時は私は男ですと出力され、橋本環奈の時は何も出力されませんといった感じです。

@humans = Human.all
@humans.each |human| do
 if human.man?
  puts "私はmanです"
 end
end

余談

そもそもなぜhuman.man(インスタンス.カラム名)のような書き方で、対象インスタンスのカラムのパラメーターを取得できるのでしょうか?つまり、なぜカラムをメソッドのように使えるのでしょうか?という疑問が湧きました。
これに関しては以下リンクが参考になりました。
参考:【Rails】カラムがメソッドのように使えるのはなぜ?

要はActive Recordを継承したクラスはインスタンス.カラム名というメソッドのような使い方ができるようになるということでした!つまりActive Recordのクラスの中にこのような挙動になる設定が書いてあるだろうってことだけ認識して私は満足しました笑

Discussion