2. ActiveRecord(2)
2012/09/24 シナジーマーケティング(株) 鈴木 圭
Model 2章 ActiveRecord
- 2.1. ActiveRecord とは
- 2.2. モデルの定義
- 2.3. クエリとメソッドチェイン
- 2.4. オブジェクトの登録, 更新
- 2.5. オブジェクトの検索
- 2.6. オブジェクトの削除
- 2.7. まとめ
2.3. クエリとメソッドチェイン
ActiveRecord が提供するクエリ API を活用するには、メソッドチェインを意識する必要があります。
メソッドチェインとは、複数のメソッドを鎖のように繋げることです。
先ほどのコードでは、以下の部分でメソッドチェインを使用しています。
# (3) 参照: 名前が 'taro' であるユーザを検索. taro = User.where(:name => 'taro').first
ここでは、検索条件を指定する where メソッドと最初のレコードを取得する first メソッドをチェインしています。
その結果として、「名前が ‘taro’ である最初のユーザを取得する」というクエリが実行されます。
以後の解説では「where は検索条件を指定する」「all は全レコードを取得する」のように、
メソッドごとに説明を行いますが、メソッドチェインのことを頭の片隅に置いた上で読んでください。
例えば、「メールアドレスが @gmail.com で終わる全ユーザを検索」したいとします。
そのときは「指定した条件を満たす全レコード返すメソッド」を探すのではなく、
「where でメールアドレスが @gmail.com で終わる条件を設定した上で、all で全レコードを取得しよう」と考えましょう。
具体的には、以下のようなコードを書くことになるでしょう。
# Gmail を利用しているユーザを検索. gmail_users = User.where('email LIKE ?', '%@gmail.com').all
2.4. オブジェクトの登録, 更新
オブジェクトを保存するには、save または save! メソッドを使用します。
オブジェクトがデータベースに保存されていない場合は新しく登録 (INSERT) され、
データベースに保存されている場合は更新 (UPDATE) されます。
user = User.new user.name = 'taro' user.email = '[email protected]' user.save # 登録 (INSERT) される. user = User.where(:name => 'taro').first user.name = 'たろう' user.save # 更新 (UPDATE) される.
オブジェクトが既にデータベースに保存されているかどうかは、new_record? メソッドで判定することができます。
if user.new_record? # データベースに保存されていない. else # データベースに保存されている. end
save! メソッドはオブジェクトを保存する点では save メソッドと同じです。
両者の違いは、save は保存に失敗した場合に false を返しますが、save! は例外 ActiveRecord::RecordInvalid を発生させます。
保存に失敗するケースとしては、後述するバリデーションで検証エラーとなった場合があります。
複数オブジェクトを更新する場合は、クラスメソッドの update_all を使用します。
# 名前を 'たろう' から '太郎' に更新. User.where('name=?', 'たろう').update_all('name=?', '太郎')
where は後述しますが、検索条件をしていするためのメソッドです。
上の例では name が ‘たろう’ であるユーザについて、’太郎’ という値に更新しています。
2.5. オブジェクトの検索
オブジェクトを検索するメソッドはいくつかあります。
all
全レコードを取得します。 見つからなかった場合は、空の配列を返します。User.all #=> SELECT * FROM users
特定の条件を満たす全レコードを取得する場合は、以下のように where メソッドと組み合わせます。
User.where('email LIKE ?', '%@gmail.com').all #=> SELECT * FROM users WHERE email LIKE '%@gmail.com'
find(primary_key)
指定した主キー (primary_key) を持つレコードを検索します。 見つからなかった場合は、例外 ActiveRecord::RecordNotFound が発生します。User.find(777) #=> SELECT * FROM users WHERE users.id=777 LIMIT 1
first, first!
最初のレコードを取得します。 見つからなかった場合、first は nil を返し、first! は例外 ActiveRecord::RecordNotFound を発生させます。User.first #=> SELECT * FROM users LIMIT 1
last, last!
最後のレコードを取得します。 見つからなかった場合、last は nil を返し、last! は例外 ActiveRecord::RecordNotFound を発生させます。User.last #=> SELECT * FROM users ORDER BY users.id DESC LIMIT 1