LoginSignup
431
390

More than 3 years have passed since last update.

【Rails】find・find_by・whereについてまとめてみた

Last updated at Posted at 2018-09-18

はじめに

今回はfind・find_by・whereについて紐解いていきます。

バージョン

rails:5.1.6

find

主キーに対応するレコードを取り出すことができる。

#主キー(id)が1のbookを検索
> Book.find(1)

=> #<Book:0x007fb51c8131b0
 id: 1,
 title: "hoge",
 price: 1250,
 publish: "fuga",
 created_at: Sat, 05 May 2018 05:42:47 UTC +00:00,
 updated_at: Sat, 05 May 2018 05:42:47 UTC +00:00>

主キーを複数指定することも可能

> Book.find(1,2)  #Book.find([1,2])でも可
=> [#<Book:0x007fb51b0636f0
  id: 1,
  title: "hoge",
  price: 1250,
  publish: "fuga",
  created_at: Sat, 05 May 2018 05:42:47 UTC +00:00,
  updated_at: Sat, 05 May 2018 05:42:47 UTC +00:00>
 #<Book:0x007fb51b062778
  id: 2,
  title: "test",
  price: 960,
  publish: "test",
  created_at: Sat, 05 May 2018 05:58:20 UTC +00:00,
  updated_at: Sat, 05 May 2018 05:58:20 UTC +00:00>]

主キーが見つからない場合

Book.find(100)
=> ActiveRecord::RecordNotFound: Couldn't find Book with 'id'=100

ActiveRecord::RecordNotFound例外が発生する。

複数主キーを指定し、一方が見つからなかった場合

Book.find(1,100)

=>ActiveRecord::RecordNotFound: Couldn't find all Books with 'id': (1, 100) (found 1 results, but was looking for 2)

こちらもActiveRecord::RecordNotFound例外が発生する。

findで取得したオブジェクトのクラス

Book.find(1).class
=> Book(id: integer, title: string, price: integer, publish: string, created_at: datetime, updated_at: datetime)

findで取得したオブジェクトのクラスはBook 

複数取得した場合のクラス

Book.find(1,2).class
=>Array

二つ取得した際にはActiveRecord_Relationではなく、Arrayクラスになるので注意!

findのまとめ

・主キーに対応するレコードを取り出す
・主キーを複数指定することも可能
・主キーが1つでも見つからない場合ActiveRecord::RecordNotFound例外が発生する
・findで取得したオブジェクトのクラスはBook 

find_by

与えられた条件にマッチするレコードのうち最初のレコードだけを返す。

Book.find_by(id: 2)
=>#<Book:0x007fb51b758168
 id: 2,
 title: "test",
 price: 960,
 publish: "test",
 created_at: Sat, 05 May 2018 05:58:20 UTC +00:00,
 updated_at: Sat, 05 May 2018 05:58:20 UTC +00:00>

主キー以外も検索条件にできる

#titleが「test」である最初のレコードを取得
Book.find_by(title: "test")
=> #<Book:0x007fb51b0ba748
 id: 2,
 title: "test",
 price: 960,
 publish: "test",
 created_at: Sat, 05 May 2018 05:58:20 UTC +00:00,
 updated_at: Sat, 05 May 2018 05:58:20 UTC +00:00>

条件を複数指定できる

#titleが「test」でなおかつ,priceが「960」の最初のレコードを取得
> Book.find_by(title: "test", price: 960)
=>#<Book:0x007fb51b6c9058
 id: 2,
 title: "test",
 price: 960,
 publish: "test",
 created_at: Sat, 05 May 2018 05:58:20 UTC +00:00,
 updated_at: Sat, 05 May 2018 05:58:20 UTC +00:00>

条件に一致するものがない場合

Book.find_by(title: "rails")
=> nil

nilを返す。

条件を複数指定し、1つ以上の条件が満たされなかった場合

Book.find_by(title: "test", price: 960, publish: "fuga")
=> nil

こちらも先ほど同様nilを返す。

find_byで取得したオブジェクトのクラス

Book.find_by(title: "test" ).class
Book(id: integer, title: string, price: integer, publish: string, created_at: datetime, updated_at: datetime)

find_byで取得したオブジェクトのクラスはBook

find_byのまとめ

・与えられた条件にマッチするレコードのうち最初のレコードだけを返す
・条件を複数指定することができる
・与えられた条件がない場合nilを返す
・find_byで取得したオブジェクトのクラスはBook

where

与えられた条件にマッチするレコードをすべて返す。

#titleが「test」にマッチするレコードを全て取得
Book.where(title: "test")
=> [#<Book:0x007f978ebe0960
  id: 2,
  title: "test",
  price: 960,
  publish: "test",
  created_at: Sat, 05 May 2018 05:58:20 UTC +00:00,
  updated_at: Sat, 05 May 2018 05:58:20 UTC +00:00>,
 #<Book:0x007f978ebe0780
  id: 10,
  title: "test",
  price: 800,
  publish: "fuga",
  created_at: Mon, 17 Sep 2018 15:30:55 UTC +00:00,
  updated_at: Mon, 17 Sep 2018 15:30:55 UTC +00:00>]

NOT条件

#titleが「test」以外のレコードを全て取得
Book.where.not(title: "test")
=> [#<Book:0x007fa69edaefc0
  id: 1,
  title: "hoge",
  price: 1250,
  publish: "fuga",
  created_at: Sat, 05 May 2018 05:42:47 UTC +00:00,
  updated_at: Mon, 17 Sep 2018 16:34:17 UTC +00:00>,
 #<Book:0x007fa69edaed90
  id: 3,
  title: "ruby",
  price: 1200,
  publish: "ruby",
  created_at: Sat, 25 Aug 2018 04:26:19 UTC +00:00,
  updated_at: Sat, 25 Aug 2018 04:26:19 UTC +00:00>]

AND条件

#titleが「test」で、なおかつpriceが「960」のレコードを全て取得
#Book.where(title: "test", price: 960)でも可
Book.where(title: "test").where(price: 960)
=>  [#<Book:0x007fa69c31c910
  id: 2,
  title: "test",
  price: 960,
  publish: "test",
  created_at: Sat, 05 May 2018 05:58:20 UTC +00:00,
  updated_at: Sat, 05 May 2018 05:58:20 UTC +00:00>]
#<Book:0x007fa6a0867358
  id: 11,
  title: "test",
  price: 960,
  publish: "fuga",
  created_at: Mon, 17 Sep 2018 17:07:26 UTC +00:00,
  updated_at: Mon, 17 Sep 2018 17:07:26 UTC +00:00>]

OR条件(Rails5から)

#titleが「hoge」かpriceが「800」のレコードを全て取得
Book.where(title: "hoge").or(Book.where(price: 800))
=>[#<Book:0x007fa6a08c4c10
  id: 1,
  title: "hoge",
  price: 1250,
  publish: "fuga",
  created_at: Sat, 05 May 2018 05:42:47 UTC +00:00,
  updated_at: Mon, 17 Sep 2018 16:34:17 UTC +00:00>,
 #<Book:0x007fa69ea73798
  id: 10,
  title: "test",
  price: 800,
  publish: "fuga",
  created_at: Mon, 17 Sep 2018 15:30:55 UTC +00:00,
  updated_at: Mon, 17 Sep 2018 15:30:55 UTC +00:00>]

A and B or C

#titleが「hoge」かつpublishが「fuga」のレコードまたは、priceが960のレコードを取得
Book.where(title: "hoge").where(publish: "fuga").or(Book.where(price: 960))
[#<Book:0x007fa6a08d56c8
  id: 1,
  title: "hoge",
  price: 1250,
  publish: "fuga",
  created_at: Sat, 05 May 2018 05:42:47 UTC +00:00,
  updated_at: Mon, 17 Sep 2018 16:34:17 UTC +00:00>,
 #<Book:0x007fa6a08d5588
  id: 2,
  title: "test",
  price: 960,
  publish: "test",
  created_at: Sat, 05 May 2018 05:58:20 UTC +00:00,
  updated_at: Sat, 05 May 2018 05:58:20 UTC +00:00>,
 #<Book:0x007fa6a08d5448
  id: 11,
  title: "test",
  price: 960,
  publish: "fuga",
  created_at: Mon, 17 Sep 2018 17:07:26 UTC +00:00,
  updated_at: Mon, 17 Sep 2018 17:07:26 UTC +00:00>]

条件にマッチしなかった場合

Book.where(title: "fuga")
=> []

ActiveRecord_Relationクラスを返す。空の配列ではないので注意。

whereで取得したオブジェクトのクラス

Book.where(title: "hoge").class
=> Book::ActiveRecord_Relation

whereで取得したオブジェクトのクラスはBook::ActiveRecord_Relation

whereのまとめ

・与えられた条件にマッチするレコードをすべて返す。
・NOT条件
・AND条件
・OR条件
・条件にマッチしない場合は空の配列を返す
・取得したオブジェクトのクラスはBook::ActiveRecord_Relation

終わりに

お疲れ様でした(^_^)
もっと詳しく知りたい方はこちらに記載されております。
ご意見やご質問等ございましたらコメントいただけると幸いです。

参考

RAILS GUIDES

431
390
2

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
431
390