前回はActiveRecordを使った参照について解説しましたが、今回は登録、更新、削除などの更新系を中心に見ていきます。
前回の記事では、Ruby on Railsのモデル層を担当するActiveRecordの概要と参照系の操作について解説しました。今回は、登録、更新、削除などの更新系の機能を中心に見ていきます。
登録・更新の際には、モデルに不正な値が保存されないようにデータをチェックして、問題があれば保存しないようにする「検証」(Validation)の仕組みが走ります。この検証機能の背後には、ActiveRecordのコールバックという仕組みがあります。コールバックを使うことで、登録、更新、検証、削除処理の前後に様々な処理を追加できます。今回と次回の2回にわたって、ActiveRecordの更新系操作のやり方とともに、検証、コールバックについて詳しく解説していきます。また、検証メッセージはローカライズのニーズが強い箇所なので、併せてRailsの国際化の仕組みについても触れます。
なお、ActiveRecordには、例えば「店」と「店員」のように、関係のあるモデル同士(テーブル同士)をオブジェクト指向に沿った形で紐付ける仕組みとして「関連」(Association)があります。関連は非常に重要かつ魅力的な機能ですが、説明が複雑になるため、次々回に詳しく説明することにします。
本記事を読み進めるにあたって、もう一度、ActiveRecordとRDBの関係を整理しておきましょう。ActiveRecordは、RDBの世界をオブジェクトの世界にマッピングします。基本的には、1つのテーブルが1つのActiveRecordクラスに対応し、1つのレコードが1つのActiveRecordインスタンスオブジェクトに対応します。なお、本記事では、ActiveRecordインスタンスオブジェクトのことをActiveRecordオブジェクトと呼ぶことにします。
従って、今回解説する更新系の操作は次のような意味になります。
登録は基本的に次の2つのステップで行います。
このために利用するメソッドは、1と2を別々に行うか同時に行うかと、プログラマがその保存が成功すると「信じている」かそうでないかによって、以下の表のように4つに分類することができます。
保存は失敗するかもしれない | 保存が成功すると信じている | |
---|---|---|
1と2を別々に行う | (1) instance.save | (3) instance.save! |
同時に行う | (2) ModelClass.create | (4) ModelClass.create! |
表1 登録のための4つの基本的な方法 |
表1の(1)と(2)の違いは、2つのステップを自分で順番に行うか、モデルクラス側でいっぺんにやってもらうかの違いです。また、返り値も異なります。
まずは(1)のsaveについて見ていきましょう。saveを使用する場合は、あらかじめオブジェクトをnewなどで作成しておく必要があります。
user = User.new(:name => 'yuki.torii', :email => 'xxx@everyleaf.com') if user.save … else … end
saveの返り値は、保存が成功したときはtrue、失敗したときはfalseとなります。
保存が失敗するとはどういうことでしょうか? 保存が失敗する主な原因は、検証を通らないことです。例えば、必須の入力項目をユーザーが入れなかったときなどに発生します。
createを使うと、オブジェクトの生成と保存を1行で指示することができます。簡潔に書けますね。
obj = User.create(:name => 'yuki.torii', :email => 'xxx@everyleaf.com')
createの返り値は、生成されたオブジェクトになります。ここでひとつ注意すべき点があります。それは、保存が成功してもしていなくても、返り値は同じく生成されたオブジェクトとなることです。保存されたかどうかを確認するには、例えば次のようにオブジェクトを調べる必要があります。
if obj.new_record? # あれ、保存されていない! ... else ... end
そのため、保存に失敗する可能性を懸念する場合は、(4)のcreate!のほうが使い勝手が良いかもしれません。
両者の使い分けとしては、生成と保存を同時に行って良い場合は、簡潔に書けるcreate/create!を使い、そうでないときはsave/save!を使うようにすると良いでしょう。後者の例としては、次のようなケースがあります。
save/save!は、新規データの登録と、既存データの更新の双方に使うことが出来るメソッドとなっているため、上記の2つめのようなケースで使うのに適しているのです。
saveとsave!、createとcreate!は基本的な動作は同じで、保存に失敗したときの動作だけが異なります。これらの4つのメソッドで、保存に失敗したときの動作は次のようになります。
メソッド | 保存に失敗したときの動作 |
---|---|
save | falseが返る |
create | 生成されたオブジェクトが返る。オブジェクトはnew_record?のまま |
save! | 例外が発生する |
create! | 例外が発生する |
一般的にプログラミングでは、例外は「例外的な失敗」に対して使います。つまり、save!やcreate!は、プログラマが次のように考えている時に使うべきメソッドといえます。
逆に、saveやcreateは、「ユーザーの入力次第では保存が失敗するかもしれない。その場合は別途、対応しよう」と考えるような場面で使うのに適しています。
Copyright © ITmedia, Inc. All Rights Reserved.