『なんか簡単にDB操作してくれる』くらいのイメージから脱却しようとするお話。
mysqlのクエリをしっかり把握しながらActiveRecordを利用している案件を通じてDB関係の知識を入れていっている中で、ActiveRecordもなんかよく分からないけど、こう書いておけばOK、くらいの身につき方からそろそろおさらばしようといことで書きます。
そもORMとは何故生まれるに至ったのか?
Object Relational Mapping、通称、ORM(O\Rマッパー)です。このライブラリの役割は、RDBとオブジェクト指向言語の橋渡しです。なぜ、橋渡しが必要なのかというと、rubyというのはオブジェクト指向言語であり、オブジェクト指向のパラダイムは、ソフトウェア工学に基づいていますが、DBのリレーショナル技術は数学の原則に基づいているので技術的な根幹部分の設計思想が全く違うのです。(それぞれどんな設計思想なのか具体的なところはここでは割愛します。)そして、このような差異はインピーダンスミスマッチと呼ばれています。このインピーダンスミスマッチによって、各々の技術の連携はシームレスに行うことはできない、つまり何かしらのハブを用意しなければ連携ができないということです。以上の理由から、O\Rマッパーは誕生することになったのです。
ORMのシステム論理階層における位置付け
ORMがやってくれていることは、システム論理層の中のパーシステンス層(別名データソース層)と呼ばれるデータストアに格納されるデータの永続化を行ってくれる階層部分の役割を担っているようです。インピーダンスミスマッチの解消はもちろん、ORMによってやってくれることは様々になってきます。今回取り上げるActiveRecordは、データアクセスロジックやドメインロジックを含んでいるのでドメイン層も含んでいるようです。
それではActiveRecordではどんなことをやってくれているか?
- インピーダンスミスマッチの解消
- モデルとデータ型の関連性を明示的にする
- モデル同士のリレーションを明示的にする
- dbへの書き込み前のチェック(バリデーション)
仕様(rubyコードにおけるどこがSQLのどこに対応させれているか)
Modelのクラス名がそのままDBのテーブル名と直結するが、そのテーブル名は、Modelのクラス名の複数形になる。そして、作成されるマイグレーションファイル内に定義された中身がカラム名と直結する。作られたModelのオブジェクトが、1レコードになる。
ActiveRecordのメソッドがどんなクエリを発行しているのか。
触ったものは随時追記していきたいと思います。
find
idでの検索オンリーで、そこからデータを取得できる。クエリの処理結果としてのオブジェクトを返す。
Stand.find(2)
# 発行されるクエリ
==> select `stands`.* from `stands` where `stands`.`id` = 100 limit 1
where
指定した条件に合致するレコードを取得する。クエリを実行する前の検索クエリを返す。これはActiveRecord::Relationと呼ばれている。
Stand.where(name: 'The World')
# 発行されるクエリ
===> select `stands`.* `stands` from `stands` where `stands`.`name` = 'The World'
find_by
条件に合致したレコードを1つ取得する。クエリの処理結果としてのオブジェクトを返す。
Stand.find_by(name: Star Platinum)
# 発行されるクエリ
===> select `stands`.* from `stands` where `users`.`id` = 'Star Platinum' limit 1
pluck
特定のカラムのリストを配列にして返す。つまり、クエリは実行済み。
Stand.pluck(:id)
# 発行されるクエリ
===> select `stands`.`id` from `stands`
order
指定した条件にカラムを並べ替えます。クエリを実行する前の検索クエリを返す。これはActiveRecord::Relationと呼ばれている。
Stand.order(:created_at)
# 発行されるクエリ
===> select `stands`.* from `stands` order by `stands`.`created_at` asc
技術用語じゃないんだぞ、私
一番最初にAtiveRecordという名前を聞いた時はDB関係だったので、私は勝手に技術用語だと思ってました。
Webアプリケーションに様々なフレームワークがあり、Vには様々なテンプレートエンジンがあるように、Mにも様々なORMがあるということですね。ORMはライブラリで、ActiveRecordはORMライブラリの一種。いわゆる所の固有名詞。
こういう恥も戒めとして記しておきます。
参考文献
オブジェクト関係マッピング
今だからデータアクセスを真剣に考える!
O\Rマッピングツールに対する誤解をときたい
RailsのActiveRecord
Active Recordの色々なメソッドの返り値
【Rails5】Active Record のクエリ