DBからデータ取得する際にfindとwhereの違いに苦しんだ話
Railsを学び初めて約6ヶ月になりましたが、がっつりRailsを勉強しているわけでもないのでなんとなく使っていて動くけど、ちゃんと理解していない部分がまだまだたくさんあります。
今日はデータベース操作でMysqlからデータを取得する際に、findとwhereの違いについて4時間悩まされた話を書いていきます。
やりたかったこと
Railsを使って、お気に入りのCDアルバムを記録する機能を作っています。
その中で、あるアルバムをお気に入りしている全ユーザー情報を表示したいと思っています。
データベースのイメージ
User | n ----- 1 | 中間テーブル | 1 ------ n | Album |
ハマったこと
まずアルバムの情報が欲しいためあるAlbumインスタンスを取得します。
(既に登録されている前提)
# アルバム名とアーティスト名が一致するアルバムのインスタンスを取得 @albm = Album.where(album: album, artist: artist) # そのアルバムをお気に入りしているユーザーのインスタンスを取得 @users = @albm.favorite_users
どう見てもこれでOKだろうと自信満々に保存すると次のエラーに怒られました。
undefined method `favorite_users' for #
要は@albmはfavorite_usersメソッドなんて持ってないぞ!と言っています。その原因は調べても調べてもわかりませんでした。
そしてrails consoleを使って「find」は上手くいくけど、「where」だと上手くいかないという事実を漸く見つけ解決に繋がりました。
findはインスタンスを返すが、whereは範囲を絞るのみ
解決方法
# アルバム名とアーティスト名が一致するアルバムのインスタンスを取得 @albm = Album.where(album: album, artist: artist).first
とすることで解決しましたが、ブログを書きながら下記でもできることが分かったのでfind_byを使うことにしました。
# アルバム名とアーティスト名が一致するアルバムのインスタンスを取得 @albm = Album.find_by(album: album, artist: artist)
以上、おそらく初心者が陥りやすそうなfindとwhereの違いでした。
参考サイト
qiita.com