バージョン
- ruby 3.2.2
- Rails 6.1.7.6
データを取得するために、深く考えずに使用していたfindメソッドとwhereメソッド。だが、スクールで課題に取り掛かっていた時に、得られる結果に奥深い違いがあることを知り、追求したくなったので、とりあえず現時点でわかったことをまとめたいと思います。
今回、tasksテーブルが以下のように定義されている。
name | content | created_at | updated_at | 以下、関係ないので省略... |
---|
あるタスクの内容(content)のデータを取得しようとwhereを使ったら、エラーになった!!なぜだ!!
task.content
という形で、あるタスクの内容のデータを取り出すために、まず、
task = Task.find(39)
として、idが39のデータを取り出そうとしたが、この日の私は、最近findばかり使用しているから、whereにも慣れたいなと考え、whereを用いてデータを取得した。
task = Task.where(id: 39)
そして、
task.content
を実行すると、
エラーになってしまう!!なぜだ!!idが1つしかないから、変数taskには1つのデータしか入ってないはずなのに。
そこで、今度は、findで行ってみる!
今度はちゃんと、task.content=「ホットケーキ」
が取得できた!
同じように1つのデータを取得していると思ってたけど、データの形に違いがあるみたい!!
whereで取得した方は
ActiveRecord::Relation
となっている!
ActiveRecord::Relation に入る前に、ActiveRecordを復習
ActiveRecord::Relation
の理解に入る前に、ActiveRecord
についても復習しておく。
ActiveRecord
とは、Ruby
のオブジェクト(Object
)とリレーショナルデータベース(Relational Database
)の対応づけ(Mapping
)を行っている。
オブジェクト(Object
)とリレーショナルデータベース(Relational Database
)の対応づけ(Mapping
)のことを、ORM
という。つまり、ActiveRecord
とは、Ruby on Rails
のORM
であるということ。
わかりやすく説明すると、Ruby on Rails
において、DBの操作をするために、Ruby
言語を用いてDBのテーブルとのデータのやりとりを行うことができるライブラリのことをActiveRecord
という。
そして、ActiveRecord::Relationとは??
私と同じように、この違いを疑問に考えた方の記事やActiveRecord::Relation
に関する記事があったので、それを元にまとめてみます。
まず、
そもそも、
今回のwhereのような、ActiveRecord::Relation
を返すメソッドというのは、メソッドを実行した時点で、データベースに対して、
「指定したデータを持ってきて〜」というクエリが、まだ発行されていないらしい!
逆に、findの方は、メソッドを実行した時に、
「指定したデータを持ってきて〜」というクエリが発行される
ので、変数の方に(今回は変数task)データが代入され、task.content
で値を取り出すことができる!
今までよく使用した「all」 「order」メソッドも、where同様、 ActiveRecord::Relationを返すメソッド とのこと。
「find_by」「last」「first」などは、findと同様、クエリがメソッド実行時に発行され、データを見つけて取ってきてくれるメソッドとのこと。つまり、 配列やオブジェクトを返すメソッド
find、find_by、whereの違いから引用
find、find_byメソッドは、検索結果のインスタンス(オブジェクト)(簡単にいうと、検索結果のデータがつまったもの)を返すが、
whereメソッドは、検索結果をオブジェクトとして返しているのではなく、検索するためのプログラムを発生させ、結果を表示しているだけの状態(うまく説明できない・・・)
もう少し噛み砕くと、whereの方は、データを引っ張ってくる準備をしただけ(検索するためのプログラムを発生させ、結果を表示しているだけの状態)で、データそのものは変数taskには入らないが、findの方は、検索結果のデータを引っ張ってきて、データが入ったインスタンス変数を作ってくれるらしい!
なるほど〜〜〜!なんとなく、わかった!!
そして、何気なく使用していた、findとwhereだけど、今後は使い分けに注意していこうと思いました!
また、
プログラミングって奥深いと実感!まーだまだこれからも学ぶことが沢山あると実感しました!
参考にさせて頂いた記事
find、find_by、whereの違い
ActiveRecord::Relationのメソッドが何を返すのか
とても勉強になりました。ありがとうございました!