11
18

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.

【Rails】カテゴリー機能の実装

Posted at

目標

ezgif.com-video-to-gif.gif

開発環境

・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

前提

下記実装済み。

Slim導入
Bootstrap3導入
投稿機能実装

実装

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に設定している。

11
18
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
11
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?