【Rails】タグを追加して投稿する




















#概要
備忘録としてユーザーがタグを追加して投稿する機能の実装方法をまとめました。

#参照
以下の記事を参考にしました。
ほとんど同じですが、上手く行かなかったところを自分なりに変更しました。
https://qiita.com/nakamura9atsuya20/items/6aca5c4f9d29307ec68a

#完成図
![tag_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2287171/91bbd624-4d33-a64c-89b9-78c32e493d1a.gif)




#アプリの作成
```ruby:ターミナル
$cd desktop
$rails new tag_sample
$cd tag_sample
```
#DBの作成
DB（データベース）を作成していない人は作成しましょう！
作成済みの人は無視して次のモデルの作成に進みましょう！

```ruby:ターミナル
$rails db:create
```
#モデルの作成
```ruby:ターミナル
$rails g model Post brand:integer  brand_id:integer body:string
$rails g model Brand brand:string
```

#コントローラーの作成
```ruby:ターミナル
$rails g controller posts
$rails g controller brands
```
ここでマイグレーション

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

#モデルのアソシエーションを記述
```ruby:model/Post.rb
class Post < ApplicationRecord
    belongs_to :brand
end
```
```ruby:model/brand.rb
class Brand < ApplicationRecord
    has_many :posts
end
```
#ルーティングについて
```ruby:config/routes.rrb
Rails.application.routes.draw do
  root"posts#index"
  resources :brands
  resources :posts
end
```
#post_controller
```ruby:controllers/post_controller.rb
class PostsController < ApplicationController

  def index
    @posts = Post.all
    @brands = Brand.all
    @brand = Brand.where(brand:"")
  end

  def new
    @post = Post.new
    @brand = Brand.new
  end

  def create
    post = Post.new(post_params)

    if post.save
      redirect_to :action => "index"
    else
      redirect_to :action => "new"
    end
  end

  private
  def post_params
    params.require(:post).permit(:brand, :body, :brand_id)
  end
end
```

#brand_controller
```ruby:controllers/brand_controller.rb
class BrandsController < ApplicationController

    def show
        @brand = Brand.find(params[:id])
    end

    def create
        brand = Brand.new(brand_params)
        if brand.save
            redirect_to new_post_path
        else
            redirect_to new_post_path
        end
    end

    private
    def brand_params
        params.require(:brand).permit(:brand, :brand)
    end
end
```

#Viewの編集
まずはapp/view/postsに
・index.html.erb
・new.html.erb
・show.html.erb
app/view/brandsに
・show.html.erb
を作成！

###投稿フォーム
```ruby:views/posts/new.html.erb
<%= form_for @post do |f| %>
  <div class="field">
      <%= f.label :body %>
      <%= f.text_field :body, :size => 10 %>
    </div>

    <div class="field">
      <%= f.label :brand %>
      <%= f.collection_select(:brand_id, Brand.all, :id, :brand) %>
    </div>

    <%= f.submit "投稿する" %>
<% end %>
<br>
<h2>ブランド追加</h2>
<%= form_for @brand do |brand| %>
    <div class="field">
      <%= brand.label :brand %>
      <%= brand.text_field :brand, :size => 10 %>
    </div>
    <%= brand.submit "追加する" %>
<% end %>

```
###詳細ページ
```ruby:views/posts/show.html.erb
 <% @brand.posts.each do |t| %>
    <br>
    <%= t.body %>
  <% end %>

<%= link_to 'Back', brands_path %>
```



###投稿一覧
```ruby:views/posts/index.html.erb
   <h1>Posts</h1>

<div class="posts-container">
<table>
    <thead>
        <tr>
        <th>Body</th>
        <th>Brand</th>
        <th colspan="3"></th>
        </tr>
    </thead>

    <tbody>
        <% @posts.each do |t| %>
            <tr>
                <td><%= t.body %></td>
                <td><%= t.brand.brand %></td>
            </tr>
        <% end %>
    </tbody>
</table>


  <h2>Brand別一覧</h2>      
  <% @brands.each do |t| %>
    <br>
    <%= t.brand %>
        <%= link_to 'Show', brand_path(t.id) %>
  <% end %>
</div>

<br>

<%= link_to 'New Post', new_post_path %>
```

###タグ検索結果一覧
```ruby:views/brand/show.html.erb
<h3>ブランド名「<%= @brand.brand %>」一覧</h3>
  <br>
  <% @brand.posts.each do |t| %>
    <br>
    <%= t.body %>
  <% end %>
<br>
<%= link_to 'Back', root_path %>
<%= link_to 'New Post', new_post_path %>
```
完成！
お疲れ様でした！