Rails モデルを使ったレコード検索

Rails では Active Record を利用することで、直接 SQL を書くことなしにさまざまなデータ操作ができる。

レコード検索

rails コンソールで動かして、発行される SQL も確認してみる。

1件検索

id で検索

id で検索する場合は find を使う。レコードが見つかったときはモデルのクラスのオブジェクトが返ってくる。

irb(main):008:0> Book.find(1)
  Book Load (0.2ms)  SELECT "books".* FROM "books" WHERE "books"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<Book id: 1, name: "Book 1", published_on: "2019-11-24", price: 1000, created_at: "2020-08-30 00:09:21", updated_at: "2020-08-30 00:09:21">

該当するレコードがなかったときは、例外(ActiveRecord::RecordNotFound)が発生する。

irb(main):009:0> Book.find(10)
  Book Load (0.3ms)  SELECT "books".* FROM "books" WHERE "books"."id" = ? LIMIT ?  [["id", 10], ["LIMIT", 1]]
Traceback (most recent call last):
        2: from (irb):8
        1: from (irb):9:in `rescue in irb_binding'
ActiveRecord::RecordNotFound (Couldn't find Book with 'id'=10)

id 以外で検索

id 以外で検索するときは find_by が使える。レコードが見つかったときはモデルのクラスのオブジェクトが返ってくる。

irb(main):010:0> Book.find_by(name: "Book 1")
  Book Load (0.3ms)  SELECT "books".* FROM "books" WHERE "books"."name" = ? LIMIT ?  [["name", "Book 1"], ["LIMIT", 1]]
=> #<Book id: 1, name: "Book 1", published_on: "2019-11-24", price: 1000, created_at: "2020-08-30 00:09:21", updated_at: "2020-08-30 00:09:21">

該当するレコードがなかったときは nil が返ってくる。

irb(main):011:0> Book.find_by(name: "none")
  Book Load (0.1ms)  SELECT "books".* FROM "books" WHERE "books"."name" = ? LIMIT ?  [["name", "none"], ["LIMIT", 1]]
=> nil

find_by! は、レコードが見つかったときは find_by と同じ動作だが、レコードが見つからなかったときは、find のように例外(ActiveRecord::RecordNotFound)を発生させる点が異なる。

irb(main):013:0> Book.find_by!(name: "none")
  Book Load (0.2ms)  SELECT "books".* FROM "books" WHERE "books"."name" = ? LIMIT ?  [["name", "none"], ["LIMIT", 1]]
Traceback (most recent call last):
        1: from (irb):26
ActiveRecord::RecordNotFound (Couldn't find Book)

複数検索

複数のレコードを検索するときは、where を使う。データが見つかったときは、ActiveRecord::Relation クラスの配列のようなオブジェクトが返ってくる。

irb(main):014:0> Book.where("price > ?", 3000)
  Book Load (0.6ms)  SELECT "books".* FROM "books" WHERE (price > 3000) LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Book id: 4, name: "Book 4", published_on: "2019-08-24", price: 4000, created_at: "2020-08-30 00:09:21", updated_at: "2020-08-30 00:09:21">, #<Book id: 5, name: "Book 5", published_on: "2019-07-24", price: 5000, created_at: "2020-08-30 00:09:21", updated_at: "2020-08-30 00:09:21">]>

該当するレコードがなかったときは、空の ActiveRecord::Relation クラスのオブジェクトが返ってくる。

irb(main):015:0> Book.where("price > ?", 100000)
  Book Load (1.1ms)  SELECT "books".* FROM "books" WHERE (price > 100000) LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

いろいろな条件を組み合わせる

例:2000円以上の Book を 2冊、安い順に取り出す

irb(main):018:0> Book.where("price >= ?", 2000).limit(2).order(:price)
  Book Load (0.3ms)  SELECT "books".* FROM "books" WHERE (price >= 2000) ORDER BY "books"."price" ASC LIMIT ?  [["LIMIT", 2]]
=> #<ActiveRecord::Relation [#<Book id: 2, name: "Book 2", published_on: "2019-10-24", price: 2000, created_at: "2020-08-30 00:09:21", updated_at: "2020-08-30 00:09:21">, #<Book id: 3, name: "Book 3", published_on: "2019-09-24", price: 3000, created_at: "2020-08-30 00:09:21", updated_at: "2020-08-30 00:09:21">]>

Active Record では、他にもさまざまなメソッドが用意されている。詳しくは Rails ガイドを参照。

Active Record クエリインターフェイス - Railsガイド

参考:パーフェクト Ruby on Rails 【増補改訂版】