0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Basic 6. 会社に紐づくスタッフの作り方 Staff、リレーションの説明

Last updated at Posted at 2019-09-21

先週の復習

RESTful APIとは?

???

MVCとは?

???

Coach: show, edit, update, destroyのページは作れましたか?

rake routesコマンドの確認

コンソールで

rake routes

と打ってみよう。

またroutingをシンプルにしよう

config/routes.rb
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'

この部分を削除して

config/routes.rb
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. 会社に紐づくスタッフのページを実装していこう

スクリーンショット 2020-04-21 17.48.28.png

4.1. モデルを作成する

rails generate model Staff name:string title:string
rails db:migrate

4.2. controllerとviewを作成する

ネストしたroutingの書き方はこのように書きます。

config/routes.rb
# resources :companies
# の行を全て消して下記を追加してください。

resources :companies do
  resources :staffs
end

下記のコマンド

rake routes

で本当に3.1で考えたpathが生成されているかチェックしてください。

次にcontrollerを作ります。

rails generate controller staffs
app/controllers/staffs_controller.rb
def index
end

viewを追加します。

app/views/staffs/index.html.erb
<p>スタッフの一覧</p>
  • rails serverで起動して実際に画面が表示出来るか確認してください。

4.3. リレーションの作成

スクリーンショット 2020-04-21 17.51.29.png

4.3.1 migrationを作ります。

  • マイグレーションとは?
rails generate migration AddCompanyIdToStaff company_id:integer
rails db:migrate

4.3.2 modelに関係を記述します

各ファイルの2行目に下記を追加。

app/models/staff.rb
belongs_to :company
app/models/company.rb
has_many :staffs

** Coachより: 3人称単数形のsを忘れないようにしよう、複数形なのか単数形なのか意識しよう。**

4.3.3 controllerを編集します

app/controllers/staffs_controller.rb
def index
  @company = Company.find(params[:company_id])
  @staffs = @company.staffs
end

4.3.4 viewを編集します

app/views/staffs/index.html.erb
<p>スタッフの一覧</p>
<% @staffs.each do |staff| %>
  <p>
  <%= staff.name %>
  <%= staff.title %>
  </p>
<% end %>

app/views/companies/show.html.erb を開き、一番下に下記を追加します

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. 新規作成・登録機能

スクリーンショット 2020-04-21 17.57.00.png
  • スタッフを新規作成 'companies/:id/staffs/new', to: 'staffs#new'
  • スタッフを登録 POST 'companies/:id/staffs', to: 'staffs#create'
app/controllers/staffs_controller.rb
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/staffs/new.html.erb
app/views/comments/new.html.erbをコピペして編集してみよう

その時に
app/views/comments/_formもコピペする必要があるのでしよう
app/views/staffs/_form.html.erb
<%= 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. 編集・更新機能

スクリーンショット 2020-04-21 17.57.48.png
  • スタッフの編集 'companies/:id/staffs/:id/edit', to: 'staffs#edit'
  • スタッフを更新 PATCH 'companies/:id/staffs/:id', to: 'staffs#update'
app/controllers/staffs_controller.rb
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/views/staffs/edit.html.erb
app/comments/edit.html.erbをコピペして編集してみよう

8. 詳細機能・削除機能

スクリーンショット 2020-04-21 17.59.55.png
  • スタッフの詳細を表示 'companies/:id/staffs/:id', to: 'staffs#show'
  • スタッフを削除 DELETE 'companies/:id/staffs/:id', to: 'staffs#destroy'
app/controllers/staffs_controller.rb
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/views/staffs/show.html.erb
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のファイル

app/views/staffs/new.html.erb
<h1>New Staff</h1>

<%= render 'form', staff: @staff %>

<%= link_to 'Back', company_staffs_path(@company) %>
app/views/staffs/_form.html.erb
<%= 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ファイル

app/views/staffs/edit.html.erb
<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ファイル

app/views/staffs/show.html.erb
<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) %>

削除リンクの追加

app/views/staffs/show.html.erb
<%= link_to 'Destroy', company_staff_path(@company, @staff), data: { confirm: 'Are you sure?' }, method: :delete %> 
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?