herokuではじめるrailsプログラミング入門 6-3節「複数モデルの連携」
DESCRIPTION
HerokuではじめるRailsプログラミング入門 (テキスト輪読) http://www.groupy.jp/study_groups/1/study_group_schedules/4 6-3節「複数モデルの連携」の説明スライドです。TRANSCRIPT
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 samplename :stringage :integermail :stringtel :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 memosample_id :integertitle :stringcomment :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
Sampleid
id
sample_idhas_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対多」で関連付ける
Sampleid
Memo
id
sample_idhas_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_tohas_oneと逆の立場で1対1を実現する。
図6-35
– belongs_toは、has_oneの裏返し。外部キーのあるMemoから、関連付けられているSampleを取り出せる。
Memo
Sampleid
id
sample_idbelongs_to