【Rails】投稿カテゴリ機能（メモ）

#   目標
* カテゴリ機能の実装

# 環境
* Rails: 6.1.3
* ruby: 3.0.0
* mac: OS

# 前提
* 簡易的なTodoApp
* 投稿機能実装済


# 実装
#### `category`モデル作成

```ruby:ターミナル
$ rails g model Category name:string
```
マイグレーションファイル生成。

```ruby
class CreateCategories < ActiveRecord::Migration[6.1]
  def change
    create_table :categories do |t|
      t.string :name

      t.timestamps
    end
  end
end
```


```ruby:
$ rails db:migrate
```

####postテーブルにカテゴリカラムを追加

```ruby:ターミナル
$ rails g migration AddCategoryIdToPosts category_id: integer
```

マイグレーションファイル生成。

```ruby
class AddCategoryIdToPosts < ActiveRecord::Migration[6.1]
  def change
    add_column :posts, :category_id, :integer
  end
end
```



```ruby:ターミナル
$ rails db:migrate
```

#### モデルの関連付け（アソシエーション）

`post`は複数のカテゴリを持てるので`has_many :categories`

```ruby:app/models/post.rb
class Post < ApplicationRecord
  has_many :categories
```

カテゴリは１つの投稿に属しているので`belongs_to :post`

```ruby:app/models/category.rb
class Category < ApplicationRecord
   belongs_to :post
```
####ルーティング記述

```ruby:config.routes.rb
Rails.application.routes.draw do
   resources :categories
end
```
####`category`コントローラ作成

```ruby:ターミナル
$ rails g controller categories 
```
生成されたコントローラに記述。

```ruby:app/controllers/categories_controller.rb
class CategoriesController < ApplicationController

  def index
    @categories = Category.all
  end

  def create
    @category = Category.new(category_params)
    @category.save
  end
end

private

def category_params
  params.require(:category).permit(:name)
end
```

```ruby:app/controllers/posts_controller.rb
private

def post_params
  params.require(:post).permit(:content, :title, :category_id)
end
```

####ビュー記述
カテゴリを追加できるフォーム。

```erb:app/views/categories/new.html.erb
<h2>カテゴリの追加　</h2>
 <%= form_with model: @category, local: true do |f| %>
    <div class='from_input'>
      <%= f.label :name %>
      <%= f.text_field :name %>
    </div>
    <div class="form_action">
      <%= f.submit "登録する", class: "btn btn-primary" %>
    </div>
 <% end %>

```

---


![スクリーンショット 2021-08-31 1.22.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927584/a53cfe06-37ce-8a8a-6976-f9c7ae7620d7.png)
----
追加したカテゴリを確認できます。



```erb:app/views/categories/index.html.erb
<h1>カテゴリ一覧</h1>
  <table class="table table-hover">
    <tbody>
      <% @categories.each do |cate| %>
        <tr>
          <td><%= link_to cate.name, posts_path(category_id: cate.id) %></td>
          <td><%= cate.created_at.to_s(:datetime_jp) %>作成</td>
        </tr>
      <% end %>
    </tbody>
  </table>
```
---
![スクリーンショット 2021-08-31 1.52.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927584/830d7d9a-071c-0753-541a-73181a8ebcf0.png)
---
新しい投稿をする際にカテゴリを選択できるようにフォームに追記。

```erb:app/views/posts/new.html.erb

    <h2>投稿ページ</h2>
    
    <%= form_with model: @post do |f| %>
        <div class="form-input">
            <%= f.label :title, 'タイトル' %>
            <%= f.text_field :title, class: "form-control" %>
        </div>
        <div class="form_input">
            <%= f.label :content, '本文' %>
            <%= f.text_field :content, class: "form-control" %>
        </div>
        
        <div class="form_input">
            <%= f.label :category_id %>
            
            <%= f.collection_select :category_id, Category.all, :id, :name, { prompt: '選択してください' }, class: 'form-control' %>
        </div>
        <div class="form_action row">
            <%= f.submit "投稿する", class: "btn btn-primary"%>
        </div>
    <% end %>
```
---
![スクリーンショット 2021-08-31 2.06.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927584/413fc9ca-5856-5805-8e48-cdcc42c4f46c.png)
--
これでカテゴリが選択できます。

# まとめ
今後も使う可能性のある機能だと思うので備忘録として残しておきます。