#はじめに
今回は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