(備忘録)ActiveRecord::Relationのwhereに詰まった話
whereとActiveRecord::Relationの理解が不十分だったので自分用メモとして残します。 まず早速例題。下記が正しいかどうか。
users = User.where(name: "taro") users.name
答えはノー(自分はこれ正しいと思ってました)。解説としては、
- whereで取得できるものはActiveRecord::Relationであり、複数の要素が入っている配列のようなもの(厳密には違う)。 その為users.nameの時点でエラーとなる。
※ActiveRecord::Relation...(User::ActiveRecord_Relation はこれの子クラス)は,検索条件を組み立てるもので,これ自体は検索結果を表してはいない。検索結果のオブジェクトとは異なる。
【続・find と where の違い 】ActiveRecord::Relation を学ぶ。 - Qiita ActiveRecord の find と where の違い。 - Qiita
最初の例題は下記のようにするとエラーがなくなる
users = User.where(name: "taro") users.pluck(:name) ※pluck 指定したカラムのレコードの配列を取得する
また下記はその他の例
author = Author.first books = author.books.where(title: "hoge") books.destroy_all
whereでtitleがhogeの配列を取得してそれを消そうとしているが単にbooks.destroyとしてしまうとエラーが出る。 (配列形式のオブジェクトに削除処理を実行しても、何番目の要素を削除すれば良いかが分からない。[hoge, foo].destroy --> 何を削除する?) 配列形式で取得したオブジェクトを全件削除する場合は、destroy_allを使う。 destroy_all | Railsドキュメント
またbooks.firstのように単体のインスタンスを取ってきて、それに対してdestroyをすることは可能。
author = Author.first books = author.books.where(title: "hoge") books.first.destroy