HerokuではじめるRailsプログラミング入門
[6-3節] 複数モデルの連携
2013/9/21(土)
@makopi23
2
自己紹介
● Ruby初心者です。
● 今回が2回目の参加です。
●
前回のブログ書きました。
http://makopi23.blog.fc2.com/blog-entry-100.html
3
アソシエーションとは?
●
テーブル間の関連付けを管理する機能。
● 要するに、データベースの外部キー(Foreign Key)制約を
Railsのフレームワーク側で保証する仕組み(らしい)。
● 今回の範囲は、写経してHerokuにデプロイ済み。
http://makopi23-rails-chapter06.herokuapp.com/memo/index
http://makopi23-rails-chapter06.herokuapp.com/sample/index
(アソシエーションは has_many の状態でデプロイ)
4
今回考える例
● モデル「Sample」
名前、年齢、メールアドレス、電話番号といった情報を保管した個人
情報データベース。(P.200)
● モデル「Memo」
投稿者の名前、タイトル、コメントといった情報を保管するための
データベース。(P.297)
● SampleもMemoも、両方とも人の情報を持っている。
● ここで、投稿する情報(Memo)を、Sampleと関連付けるこ
とができれば、人に関する同じ情報をあちこちのテーブル
に保存する必要はなくなる。
5
Sampleモデル
● P.200で、rails generateコマンドでモデル「Sample」を作成した。
rails generate model sample
name :string
age :integer
mail :string
tel :string
id name age mail tel create_at update_at
1 taro 10 taro@xxx 090-xxxx-xxxx 2013-9-22 ... 2013-9-22 ...
2 hanako 20 hanako@xxx 090-yyyy-yyyy 2013-9-22 ... 2013-9-22 ...
3 makopi23 3 makopi23@xxx 090-zzzz-zzzz 2013-9-22 ... 2013-9-22 ...
CREATE TABLE sample(
id SERIAL PRIMARY KEY,
name VARCHAR(255),
age INT(11),
mail VARCHAR(255),
tel VARCHAR(255),
create_at DATETIME,
update_at DATETIME);
railsコマンド SQL(MySQL)
id, create_at, update_at が自動付与される(P.225)
6
Memoモデル
● P.297で、rails generateコマンドでモデル「Memo」を作成する。
rails generate model memo
sample_id :integer
title :string
comment :string
id sample_id title comment create_at update_at
1 3 third title 3番目のメモ 2013-9-22 ... 2013-9-22 ...
2 1 second title 2番目のメモ 2013-9-22 ... 2013-9-22 ...
3 2 first title 1番目のメモ 2013-9-22 ... 2013-9-22 ...
CREATE TABLE memo(
id SERIAL PRIMARY KEY,
sample_id INT(11),
title VARCHAR(255),
comment VARCHAR(255),
create_at DATETIME,
update_at DATETIME);
railsコマンド SQL(MySQL)
id, create_at, update_at が自動付与される(P.225)
関連するsampleのID番号 タイトルのテキスト 投稿するメッセージ
7
Memoモデルの作成(つづき)
リスト6-31: models/memo.rb
リスト6-32: db/migrate/20130919154645_create_memos.rb
マイグレーションを実行するコマンド ⇒ rake db:migrate
8
MemoControllerを作る
コマンド実行: rails generate controller memo index
⇒ controllers/memo_controller.rbが生成される。
次に、右記のようにスクリプト
を記述する。
(リスト6-33)
9
indexビューテンプレートを作る
リスト6-34: views/memo/index.html.erb
10
indexビューテンプレートを作る(続き)
リスト6-35: views/layouts/partials/_mymemo.html.erb
⇒ index.html.rbから利用されるパーシャルの作成
リスト6-36: config/routes.rb
⇒ ルート情報を追加
11
これでMemoは完成!
図6-30: http://localhost:3000/memo/index
12
1対1の関係を作る「has one」
●
「アソシエーション」にはいくつか種類がある。
– has_one
あるテーブルのレコードを、別のテーブルのレコードに「1対1」
で関連付ける
図6-24
– has_oneは、外部キーで指定したモデルとの間に1対1の関連
付けを行う。ここでは、Sampleのidと、Memoのsample_idが
一致する最初の1つが関連付けられる。
Memo
Sample
id
id
sample_id
has_one
13
1対1の関係を作る「has one」(続き)
リスト6-37: models/sample.rb
注意する必要があるのは、「外部キーがあるモデルではなくて、外
部キーで関連付けている側のモデルにhas_one指定を行う」という
点である。
CREATE TABLE sample(
id SERIAL PRIMARY KEY,
name VARCHAR(255),
age INT(11),
mail VARCHAR(255),
tel VARCHAR(255),
create_at DATETIME,
update_at DATETIME);
CREATE TABLE memo(
id SERIAL PRIMARY KEY,
sample_id INT(11),
title VARCHAR(255),
comment VARCHAR(255),
create_at DATETIME,
update_at DATETIME,
UNIQUE KEY (sample_id)
FOREIGN KEY (sample_id)
REFERENCES sample(id);
14
has_oneしたレコードを取得する
リスト6-39: views/layouts/partials/_mydata.html.erb
mydata.memoがnilかどうかをチェックし、そうでなければ
mydata.memo.commentを書き出している。
なおmydata.memoは、Sampleインスタンスに関連付けられた
Memoインスタンスが格納されているプロパティである。
15
has_oneしたレコードを取得する(続き)
図6-32: http://localhost:3000/sample/index
スライドP.12で追加した
Memoが、Sampleに関
連付けられている。
16
1対多の関連付けをする「has many」
– has_many
あるテーブルのレコードを、別のテーブルのレコードに「1対多」
で関連付ける
Sample
id
Memo
id
sample_id
has_many
Memo
id
sample_id
Memo
id
sample_id
図6-33
17
has_manyのレコードを取り出すには? (1/3)
リスト6-40: models/sample.rb
Sampleインスタンスにmemoプロパティが用意されるが、それは
Memoインスタンスの配列になる。
CREATE TABLE sample(
id SERIAL PRIMARY KEY,
name VARCHAR(255),
age INT(11),
mail VARCHAR(255),
tel VARCHAR(255),
create_at DATETIME,
update_at DATETIME);
CREATE TABLE memo(
id SERIAL PRIMARY KEY,
sample_id INT(11),
title VARCHAR(255),
comment VARCHAR(255),
create_at DATETIME,
update_at DATETIME,
UNIQUE KEY (sample_id)
FOREIGN KEY (sample_id)
REFERENCES sample(id);
18
has_manyのレコードを取り出すには? (2/3)
リスト6-41: views/layouts/partials/_mydata.html.erb
mydata.memo.each do |data| というようにmemoからインスタンス
を取得しdataに代入して繰り返しを実行している。
そしてdata.commentを出力している。
<ol>指定により箇条書き連番で出力される。
19
has_manyのレコードを取り出すには? (3/3)
図6-34: http://localhost:3000/sample/index
ID=4の人に、コメントが
2つ紐づいている。
20
has_oneを逆の立場から見た「belongs_to」
●
「アソシエーション」にはいくつか種類がある。
– belongs_to
has_oneと逆の立場で1対1を実現する。
図6-35
– belongs_toは、has_oneの裏返し。外部キーのあるMemoか
ら、関連付けられているSampleを取り出せる。
Memo
Sample
id
id
sample_id
belongs_to

HerokuではじめるRailsプログラミング入門 6-3節「複数モデルの連携」