目標
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina
前提
下記実装済み。
実装
1.モデル
①カテゴリーモデル・テーブルを作成
ターミナル
$ rails g model Category name:string
ターミナル
$ rails db:migrate
schema.rb
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
②booksテーブルにカラムを追加
ターミナル
$ rails g migration AddCategoryIdToBooks category_id:integer
ターミナル
$ rails db:migrate
schema.rb
create_table "books", force: :cascade do |t|
t.integer "user_id"
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "category_id"
end
③各モデルを編集
book.rb
# 追記
has_many :categories, dependent: :destroy
dependent: :destroy
➡︎ 該当のカテゴリーが削除された時、紐付いている本も一緒に削除する。
category.rb
# 追記
belongs_to :book
2.コントローラー
①categories_controller.rb
を作成・編集
予めindexとeditのビューを作成しておく。
ターミナル
$ rails g controller categories index edit
categories_controller.rb
class CategoriesController < ApplicationController
before_action :set_category, only: [:edit, :update, :destroy]
def index
@category = Category.new
@categories = Category.all
end
def create
@category = Category.new(category_params)
if @category.save
redirect_to categories_path
else
@categories = Category.all
render 'index'
end
end
def edit
end
def update
if @category.update(category_params)
redirect_to categories_path
else
render 'edit'
end
end
def destroy
@category.destroy
redirect_to categories_path
end
private
def set_category
@category = Category.find(params[:id])
end
def category_params
params.require(:category).permit(:name)
end
end
②books_controller.rb
のストロングパラメーターにcategory_id
を追加
books_controller.rb
def book_params
params.require(:book).permit(:title, :body, :category_id)
end
3.ルーティング
routes.rb
# 追記
resources :categories, except: [:new, :show]
except: [:new, :show]
➡︎ newとshow以外のアクションをルーティングに追加する。
4.ビュー
categories/index.html.slim
.row
.col-xs-3
= form_with model: @category, local: true do |f|
= f.label :name, 'カテゴリー名'
br
= f.text_field :name, class:'form-control'
br
= f.submit '追加', class: 'btn btn-primary btn-block'
.col-xs-9
table.table
thead
tr
th
| カテゴリー名
th
th
tbody
- @categories.each do |category|
tr
td
= category.name
td
= link_to '編集', edit_category_path(category), class: 'btn-sm btn-primary'
td
= link_to '削除', category_path(category), method: :delete, data: { confirm: '本当に削除しますか?' }, class: 'btn-sm btn-danger'
categories/edit.html.slim
.row
.col-xs-3
.col-xs-6
= form_with model: @category, local: true do |f|
= f.label :name, 'カテゴリー名'
br
= f.text_field :name, class:'form-control'
br
= f.submit '保存', class: 'btn btn-primary btn-block'
.col-xs-3
books/index.html.slim
.row
.col-xs-3
= form_with model: @book, local: true do |f|
= f.label :title, 'タイトル'
br
= f.text_field :title, class:'form-control'
br
= f.label :body, '本文'
br
= f.text_area :body, class:'form-control'
br
/ 追記
= f.label :category_id, 'カテゴリー'
br
= f.collection_select :category_id, Category.all, :id, :name, { prompt: '選択してください' }, class: 'form-control'
br
= f.submit '投稿', class: 'btn btn-primary btn-block'
.col-xs-9
table.table
thead
tr
th
| 投稿者
th
| タイトル
th
| 本文
/ 追記
th
| カテゴリー
th
tbody
- @books.each do |book|
tr
td
= link_to book.user do
= book.user.name
td
= link_to book.title, book_path(book)
td
= book.body
/ 追記
td
= book.category.name
td
-if book.user == current_user
= link_to '削除', book, method: :delete, data: { confirm: '本当に削除してもよろしいですか?' }, class: 'btn-sm btn-danger'
= f.collection_select :category_id, Category.all, :id, :name
➡︎ 全カテゴリーの名前
をプルダウンメニューに表示し、値をid
に設定している。