仕事で開発をしていたところ、
「include ActiveModel::Model」というコードが出現しました。
これまで個人開発やスクールでの学習では
「モジュール」をあまりやってこなかったので
こういう見たことがないものには、苦手意識・・・。
ということで、調べてみた。
そもそもincludeとは
include
メソッドは、クラスやモジュールに他のモジュールをインクルード(Mix-in)します。引数にはモジュールを指定します(複数指定できます)。戻り値はクラスやモジュール自身です。
他のモジュールをincludeすることで
そのモジュール内で使われているメソッドとかが使えるようになる、
っていう雰囲気かな。
え、なんかクラスの継承と似てる〜。
モジュールをincludeするのとクラスを継承するの、
どう使い分ければ良いんだろう、と一瞬思った私。
引数に指定できるのはモジュールだけで、クラスは指定できません。モジュールにモジュールをインクルードすることはできます。
なるほど
- クラスを引き継ぎたい=クラスの継承
- モジュールを引き継ぎたい=include
っていう感じなんですね。
そもそもクラスって車の設計図のような概念で、
インスタンスを作るためにあるものがクラスのはず。
モジュールはインスタンスを生成するとかは関係なく、
メソッドやらが定義された意味のあるひとかたまりっていう感じですもんね。
似てるなぁとか思ってたけど、全然違うな
継承に関しても、
「犬」と「チワワ」みたいに
相関関係があるクラス同士を紐づけるべきなのに対し、
モジュールにはそういう概念が無いもんね。
あ、なんかスッキリ。
(間違ってたら教えてください)
再びinclude ActiveModel::Modelに戻る
前置きが長くなったけど、前提を踏まえた上で
もう一度さっきのコードを眺めてみる。
include ActiveModel::Model
includeに続くのはモジュールのはずだから、
ActiveModel::Modelっていうのはモジュールだね。
モジュールがどこかのディレクトリにあるのかな〜
と一瞬思ったけど、ActiveModelって書いてあるからきっと
アクティブレコードで定義されてる何かだろうな。
ActiveModel::Model
をinclude
すると、以下のような機能を使えるようになります。
- モデル名の調査
- 変換
- 翻訳
- バリデーション
ActiveModel::Model
をinclude
するクラスでは、Active Recordの場合と同様にform_for
やrender
などのAction Viewヘルパーメソッドを使えるようになりま。
なるほど、なんとなく理解。
今回いじっていた部分ですが、
モデルと紐づいたあるクラスの中にある、
DBには保存しないけど一時的に生成するデータ用のクラス
でした。(伝われ)
``````
class User < ApplicationRecord
include Confirming
class OneTimeUser
include ActiveModel::Model
include ActiveModel::Validations::Callbacks
include Confirming
end
end
`````````
ちなみに、include Confirmingっていうのもモジュールをincludeしていて
これは元々あるものではなく、開発者が任意で作成したモジュールですね
Userはモデルとして存在していてDBにも保存されるけど、
OneTimeUserはモデルが存在しないので、
普通にclassを定義したこのままの状態では
モデルに使える機能(バリデーションとか)が使えないみたい。
DBに保存しないとはいえ
form_forは使いたいし、バリデーションも使いたいし
ということでinclude ActiveModel::Modelが必要だった模様。
include ActiveModel::Validations::Callbacks
ちなみにその下にある、
include ActiveModel::Validations::Callbacks
もモジュールをincludeしているわけですが、こちらは
before_validationなどのコールバックを使用したい時に必要なようです。
モジュールに対しての苦手意識が少しなくなりましたとさ。