先週の復習
RESTful APIとは?
???
MVCとは?
???
Coach: show, edit, update, destroyのページは作れましたか?
rake routesコマンドの確認
コンソールで
rake routes
と打ってみよう。
またroutingをシンプルにしよう
get 'companies', to: 'companies#index'
get 'companies/new', to: 'companies#new', as: 'new_company'
get 'companies/:id/edit', to: 'companies#edit', as: 'edit_company'
get 'companies/:id', to: 'companies#show', as: 'company'
patch 'companies/:id', to: 'companies#update'
post 'companies', to: 'companies#create'
delete 'companies/:id', to: 'companies#destroy'
この部分を削除して
resources :companies
もう一度
rake routes
で同じものが表示されることを確認してください。
今日は
1. 1:Nのリレーションの作り方: 会社に紐づくスタッフの作り方
データに紐づくデータをどのように表現するか。
データベースがなぜ重要かと言うと、データ同士を紐付けるからです。
例えば、世の中の会社の一覧データと世の中の従業員のデータ
データの表現の仕方として、下記のどちらがいいでしょうか?
a. 会社毎にカテゴリ分けされて一つ一つの会社の従業員がわかる
b. 会社のデータと従業員のデータが紐付かないで、それぞれ別に存在する
2. IdeaとCommentの関係を考えてみよう
2.1. RESTful API for Comment
ネストしたRESTの組み立て方
HTTP Request | URL | アクション | 用途 |
---|---|---|---|
GET | /ideas/:idea_id/comments | index | あるアイデアのすべてのコメントの一覧ページ |
GET | /ideas/:idea_id/comments/:id | show | id=:idのコメントの詳細ページ |
GET | /ideas/:idea_id/comments/new | new | あるアイデアに紐づくコメントの新規作成ページ |
POST | /ideas/:idea_id/comments | create | コメントを作成するアクション |
GET | /ideas/:idea_id/comments/:id/edit | edit | id=:idのコメントの編集ページ |
PATCH | /ideas/:idea_id/comments/:id | update | id=:idのコメントの更新アクション |
DELETE | /ideas/:idea_id/comments/:id | destroy | id=:idのコメントの削除アクション |
- 先週の一般的なRESTful APIのURLの前に/ideas/:idea_idを入れるのがポイント
2.2. MVC for Comment
- app/models/comment.rb
- app/controllers/comments_controller.rb
- app/views/comments/index.html.erb
- config/routes.rb
3. 会社に紐づくスタッフ(Staff)を設計してみよう
3.1. RESTful API for Staff
ネストしたRESTの組み立て方
HTTP Request | URL | アクション | 用途 |
---|---|---|---|
GET | ? | index | ある会社のすべてのスタッフの一覧ページ |
GET | ? | show | id=:idのスタッフの詳細ページ |
GET | ? | new | ある会社に紐づくスタッフの新規作成ページ |
POST | ? | create | スタッフを作成するアクション |
GET | ? | edit | id=:idのフタッフの編集ページ |
PATCH | ? | update | id=:idのスタッフの更新アクション |
DELETE | ? | destroy | id=:idのスタッフの削除アクション |
3.2. MVC for Staff
- app/models/?
- app/controllers/?
- app/views/?
- config/routes.rb
4. 会社に紐づくスタッフのページを実装していこう

4.1. モデルを作成する
rails generate model Staff name:string title:string
rails db:migrate
4.2. controllerとviewを作成する
ネストしたroutingの書き方はこのように書きます。
# resources :companies
# の行を全て消して下記を追加してください。
resources :companies do
resources :staffs
end
下記のコマンド
rake routes
で本当に3.1で考えたpathが生成されているかチェックしてください。
次にcontrollerを作ります。
rails generate controller staffs
def index
end
viewを追加します。
<p>スタッフの一覧</p>
- rails serverで起動して実際に画面が表示出来るか確認してください。
4.3. リレーションの作成

4.3.1 migrationを作ります。
- マイグレーションとは?
rails generate migration AddCompanyIdToStaff company_id:integer
rails db:migrate
4.3.2 modelに関係を記述します
各ファイルの2行目に下記を追加。
belongs_to :company
has_many :staffs
** Coachより: 3人称単数形のsを忘れないようにしよう、複数形なのか単数形なのか意識しよう。**
4.3.3 controllerを編集します
def index
@company = Company.find(params[:company_id])
@staffs = @company.staffs
end
4.3.4 viewを編集します
<p>スタッフの一覧</p>
<% @staffs.each do |staff| %>
<p>
<%= staff.name %>
<%= staff.title %>
</p>
<% end %>
app/views/companies/show.html.erb
を開き、一番下に下記を追加します
<p><%= link_to '従業員の一覧', company_staffs_path(@company) %></p>
4.3.5 ページをロードして従業員の一覧機能が正しく動いているか確認してみよう
5. Railsのviewでのpathの組み立て方
- Pathとは、WEBページのリンクのことで、HTMLで言うところのaタグ
<a href="/companies/1/staffs">従業員の一覧</a>
などに変換されます。
/companies => companies_path
/companies/new => new_company_path
(POST /companies => companies_path )
/companies/:id => company_path(@company)
/companies/:id/edit => edit_company_path(@company)
(PATCH /companies/:id => company_path(@company) )
(DELETE /companies/:id => company_path(@company), method: :delete)
スタッフの場合を
rake routes
でチェックしてみよう。
従業員の一覧へのpathがなぜ下記なのか理解できましたか?
company_staffs_path(@company)
6. 新規作成・登録機能

- スタッフを新規作成 'companies/:id/staffs/new', to: 'staffs#new'
- スタッフを登録 POST 'companies/:id/staffs', to: 'staffs#create'
def new
@company = Company.find(params[:company_id])
@staff = @company.staffs.build
end
def create
@company = Company.find(params[:company_id])
@staff = Staff.new(staff_params)
if @staff.save
redirect_to company_staffs_path(@company)
end
end
def staff_params
params.require(:staff).permit(:name, :title, :company_id)
end
app/views/comments/new.html.erbをコピペして編集してみよう
その時に
app/views/comments/_formもコピペする必要があるのでしよう
<%= form_with(model: [@company, staff], local: true) do |form| %>
...ここの中身を埋めていこう
<% end %>
Coach: @companyや@staffのような、controllerのinstance変数とviewのinstance変数は同じものであることを説明しよう。データを表示したければ、そのinstanceを使ってデータをviewで表示しなければならない。controllerからviewにデータを受け渡す場合、決まりとして@を使わなければいけない。(@なしのcompanyやstaffは使えない)。_form.html.erbのstaffはview同士で受け渡しているので@が必要ない。
Coach: 何故form_forで2つのモデルを入れるのか。Railsの決まりです。将来的には自分たちで調べながら実装する必要があります。下記参考。
https://guides.rubyonrails.org/form_helpers.html
https://apidock.com/rails/v5.2.3/ActionView/Helpers/FormHelper/form_for
https://www.w3schools.com/html/html_form_input_types.asp
https://api.rubyonrails.org/v5.1/classes/ActionView/Helpers/FormHelper.html
7,8は宿題
7. 編集・更新機能

- スタッフの編集 'companies/:id/staffs/:id/edit', to: 'staffs#edit'
- スタッフを更新 PATCH 'companies/:id/staffs/:id', to: 'staffs#update'
def edit
@company = Company.find(params[:company_id])
@staff = Staff.find(params[:id])
end
def update
@company = Company.find(params[:company_id])
@staff = Staff.find(params[:id])
if @staff.update(staff_params)
redirect_to company_staffs_path(@company)
end
end
app/comments/edit.html.erbをコピペして編集してみよう
8. 詳細機能・削除機能

- スタッフの詳細を表示 'companies/:id/staffs/:id', to: 'staffs#show'
- スタッフを削除 DELETE 'companies/:id/staffs/:id', to: 'staffs#destroy'
def show
@company = Company.find(params[:company_id])
@staff = Staff.find(params[:id])
end
def destroy
@company = Company.find(params[:company_id])
@staff = Staff.find(params[:id])
if @staff.destroy
redirect_to company_staffs_path(@company)
end
end
app/comments/show.html.erbをコピペして編集してみよう
削除のリンクを追加してみよう
Routingについての詳しい解説を知りたい人は
詳しい説明は下記にあります。
https://railsguides.jp/routing.html
3.1の答え*
HTTP Request | URL | アクション | 用途 |
---|---|---|---|
GET | 'companies/:company_id/staffs' | index | ある会社のすべてのスタッフの一覧ページ |
GET | 'companies/:company_id/staffs/:id' | show | id=:idのスタッフの詳細ページ |
GET | 'companies/:company_id/staffs/new' | new | ある会社に紐づくスタッフの新規作成ページ |
POST | 'companies/:company_id/staffs' | create | スタッフを作成するアクション |
GET | 'companies/:company_id/staffs/:id/edit' | edit | id=:idのフタッフの編集ページ |
PATCH | 'companies/:company_id/staffs/:id' | update | id=:idのスタッフの更新アクション |
DELETE | 'companies/:company_id/staffs/:id' | destroy | id=:idのスタッフの削除アクション |
Routingの確認の仕方*
rake routes
6.のviewのファイル
<h1>New Staff</h1>
<%= render 'form', staff: @staff %>
<%= link_to 'Back', company_staffs_path(@company) %>
<%= form_with(model: [@company, staff], local: true) do |form| %>
<% if staff.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(staff.errors.count, "error") %> prohibited this staff from being saved:</h2>
<ul>
<% staff.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :title %>
<%= form.text_field :title %>
</div>
<%= form.hidden_field :company_id, value: @company.id %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
7. のviewファイル
<h1>Editing Staff</h1>
<%= render 'form', staff: @staff %>
<%= link_to 'Show', company_staff_path(@company, @staff) %> |
<%= link_to 'Back', company_staffs_path(@company) %>
8. のviewファイル
<p>
<strong>Name:</strong>
<%= @staff.name %>
</p>
<p>
<strong>Title:</strong>
<%= @staff.title %>
</p>
<p>
<strong>Company:</strong>
<%= @staff.company.name %>
</p>
<%= link_to 'Edit', edit_company_staff_path(@company, @staff) %> |
<%= link_to 'Back', company_staffs_path(@company) %>
削除リンクの追加
<%= link_to 'Destroy', company_staff_path(@company, @staff), data: { confirm: 'Are you sure?' }, method: :delete %>