2
1

データを取得するために、何気なく使用していた、findメソッド・whereメソッドそれぞれから得られる結果の違いについて

Posted at

バージョン

  • 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

を実行すると、
スクリーンショット 2024-01-28 12.56.59.png
エラーになってしまう!!なぜだ!!idが1つしかないから、変数taskには1つのデータしか入ってないはずなのに。
そこで、今度は、findで行ってみる!
スクリーンショット 2024-01-28 13.04.37.png

今度はちゃんと、task.content=「ホットケーキ」が取得できた!

同じように1つのデータを取得していると思ってたけど、データの形に違いがあるみたい!!

調べてみた!
まず、findの方。
スクリーンショット 2024-01-28 13.11.47.png

一方、whereの方
スクリーンショット 2024-01-28 13.12.35.png

whereで取得した方は
ActiveRecord::Relation となっている!

ActiveRecord::Relation に入る前に、ActiveRecordを復習

ActiveRecord::Relationの理解に入る前に、ActiveRecordについても復習しておく。
ActiveRecordとは、Rubyのオブジェクト(Object)とリレーショナルデータベース(Relational Database)の対応づけ(Mapping)を行っている。
オブジェクト(Object)とリレーショナルデータベース(Relational Database)の対応づけ(Mapping)のことを、ORMという。つまり、ActiveRecordとは、Ruby on RailsORMであるということ。

わかりやすく説明すると、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のメソッドが何を返すのか

とても勉強になりました。ありがとうございました!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1