(備忘録)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  指定したカラムのレコードの配列を取得する

pluck | Railsドキュメント

また下記はその他の例

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