libro
www.tuyano.com
初心者のためのRuby on Rails3入門

アソシエーションの利用 (4/5)

作成:2012-11-03 10:10
更新:2012-11-03 10:10

■1対多を対応させる「has_many」

しかし、メーカーと商品の場合、has_aというのはちょっとうまい関連付けとはいえませんね。メーカーからはいくつもの商品が出ていますから、すべての商品をメーカーに関連付けできたほうがいいに決まっています。

こうした関連付けを「1対多」対応といいます。これは、Railsでは「has_many」というアソシエーションとして用意されています。このhas_manyは、モデルに以下のように記述して設定します。
has_many :モデル名
さっきのhas_aと全く同じですね。これにより、関連付けたモデルの複数の項目がまとめてこのモデルに関連付けられます。――では、実際にやってみましょう。Makerクラスを下のリスト欄のように修正してみてください。

ここでは、 has_many :good としていますね。has_aと同様、外部キーのある方ではなく、ないほうに記述をします。これで関連付けができています。


■ビューテンプレートを修正しよう
では、index.html.erbを修正しましょう。先ほどのhas_aと同様に、レコードの一覧を表示するテーブルの部分を下のリスト欄にあげたように修正します。これで/makersにアクセスすると、各レコードに関連するgoodsのレコードがすべて表示されます。

ここでは、以下のようにして関連するgoodsをすべて表示しています。
    <% maker.good.each do |obj| %>
        <b><%= obj.name %></b><br>
        <%= obj.memo %><hr />
    <% end %>
maker.goodからeachでオブジェクトを順に取り出し処理していることがわかりますね。has_manyは、関連するモデルのインスタンスをすべて取り出します。このため、それらを配列にまとめてgoodに設定されるようになっているのです。これは、たとえ得られたインスタンスが1つ(あるいはゼロ)であったとしても同様で、必ず配列の形になっています。

インスタンスさえ得られれば、後は同じですね。そこから各コラムが保管されているプロパティの値を取り出して書き出すだけです。

※プログラムリストが表示されない場合

AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。

●プログラム・リスト●

※Makerクラスの修正

class Maker < ActiveRecord::Base
  attr_accessible :memo, :name, :site
  has_many :good
end


※index.html.erbの修正

<table>
  <tr>
    <th>Name</th>
    <th>Site</th>
    <th>Memo</th>
    <th>Goods</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @makers.each do |maker| %>
  <tr>
    <td><%= maker.name %></td>
    <td><%= maker.site %></td>
    <td><%= maker.memo %></td>
    <td>
    <% maker.good.each do |obj| %>
        <b><%= obj.name %></b><br>
        <%= obj.memo %><hr />
    <% end %>
    </td>
    <td><%= link_to 'Show', maker %></td>
    <td><%= link_to 'Edit', edit_maker_path(maker) %></td>
    <td><%= link_to 'Destroy', maker, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

※関連コンテンツ

「初心者のためのRuby on Rails3入門」に戻る