モデルの多対多参照

 いくつかの選択授業があるとします。各学生は0個~n個の授業を選び,各授業には0人~m人の学生が所属しています。このような関係が「多対多」です。

 モデルの作成にはrailsコマンドを使います。なお,rails grails generateの省略形です。

 モデルを作成するのと同時に,データベースのテーブルも作成する必要があります。既存または新規のマイグレーションにコードを追加します。
 必要となるテーブルは,学生のレコードと授業のレコードを結びつけるための,中間的なテーブルです。1対1の関係であれば,それぞれのモデルに参照用のカラムを追加すれば済みますが,多対多の関係ではそれでは済みません。

 マイグレーションを作成する場合はrailsコマンドを使います。

参照を追加するためのフォーム

 scaffoldを作成すると,ビューの中に_form.html.erbというファイルが作成されています。これは,オブジェクトのデータを入力するためのフォームを生成するための,パーシャルと呼ばれるコードの断片です。

 一つの電話番号に,一人の学生が関連づけられている場合を考えてみます。

 scaffoldで作成された_form.html.erbは次のようになっており,参照する学生のIDを直接入力させるようになっています。

 これでは何番のIDが何という学生に対応するのか分からないため,学生の一覧をリストボックスで表示して,そこから選ぶような形に変更します。

追加されたカラムに関する保存処理

 モデルを作成した後で,対応するテーブルにカラムを追加したくなる場合があります。このとき,コントローラーを適切に修正しなければ,データが全く保存されないという事態に陥る可能性があります。

 メソッドphone_paramsでは,いわゆるホワイトリスト処理を行い,許可された名前のパラメータ以外は受け付けないようにしています。そのため,追加したカラムの名前をホワイトリストに加えなければ,何をしてもデータが変更されないということになってしまいます。
 学生への参照を追加した場合は,以下のように変更します。

データベース初期値の設定

 db/seeds.rbにコードを記述することで,データベースの初期値を設定できます。

 リテラルデータのほか,オブジェクト同士の関連を設定することもできます。
 newで作成した場合は,saveメソッドを呼ばなければデータベースに記録されないので注意が必要です。createで作成した場合は,そのままデータベースに記録されます。関連を設定する場合は,オブジェクト名_idにオブジェクトのidを直接設定することになります。