🐮

Rails カテゴリタグを追加し検索

2023/05/07に公開

要件

  • 本の投稿をする際にカテゴリタグを追加できる
  • 作成したタグで検索ができる
  • 作成したタグのリンクをクリックすると検索ができる

完成

検索結果表示ページ

1 .カラムの追加

Bookモデルにタグを保存するために新しくカラムcategoryを作成!
#rails g migration add追加したいカラム名To追加したいモデル名 追加したいカラム名:データ型

今回だと、

rails g migration AddCategoryToBooks category:string

作成後

rails db:migrate
🏋🏻なぜmigrationファイルの書き直しだとダメなのか??

rails db:rollback で前に反映したものを未反映にしてから、
再度 rails db:migrateで反映することもできるが、、

注意点:他の開発者と共有済みのmigrationファイルを変更する場合

Gitでコミット/プッシュ済みであったり、本番環境に適用済みのmigrationファイルの場合はロールバックしてしまうとデータも消えてしまうため戻せません。

既存のmigrationファイルを編集するのではなく、変更を行う新たなmigrationファイルを追加しましょう。
例えば以下の通りです。

間違えたカラム名やデータ型を修正したい場合はカラム名を変更するmigrationファイルを追加
間違えたテーブル名を修正したい場合はテーブル名を変更するmigrationファイルを追加
共有済みのmigrationファイルの変更はできないので「変更のためのmigrationファイル」を追加して対応しましょう。

参照:https://ichigick.com/rails-edit-migration/

ちなみに、ターミナルでもカラムを確認できる!
rails runner 'puts モデル名.column_names'

categoryが作成されていることがわかる💪🏻

2.コントローラー作成、バリデーション設定

バリデーション設定

models/book.rb
validates :category, presence: true

ストロングパラメータの設定

books_controllerのストロングパラメータに:categoryを追加

books_controller.rb
  private

  def book_params
    params.require(:book).permit(:title, :body, :profile_image, :star, :category) 
  end

コントローラーを作成

TagSearchesコントローラーを作成

rails g controller Tagsearches

コントローラーへの記述は以下の通り

tagsearches_controller.rb
class TagsearchesController < ApplicationController
  def search
    @model = Book  #search機能とは関係なし
    @word = params[:content]
    @books = Book.where("category LIKE?","%#{@word}%")
    render "tagsearches/tagsearch"
  end
end

whereメソッドにSQLのLIKE句で検索条件を記述している。

<基本の記述型>

モデルクラス.where("列名 LIKE ?", "%値%")  # 値(文字列)を含む
モデルクラス.where("列名 LIKE ?", "値_")   # 値(文字列)と末尾の1文字
🏋🏻わかりやすかった記事

3.Routingの設定

get 'tagsearches/search', to: 'tagsearches#search'

4.viewページの作成

1️⃣ 投稿フォームへの追加

この部分!

:
省略
<div class="form-group">
  <label>Category</label>
  <%= f.text_field :category,class: 'form-control book_category' %>
</div>
:

2️⃣ Book作成後のbook/showページにも記述

books/show.html.erb
<td>
  <% if @book.category.present? %>
    <%=link_to@book.category,tagsearches_search_path(content:@book.category)%>
  <% end %>
</td>

category機能を作る前に投稿していたbookもあるため、categoryのない投稿は下記のように表示されてしまった。
投稿済みのデータをリセットするでもいいと思いますが、<% if @book.category.present? %>(もしcategoryがあったら?)の文を付け足しました。


⇩(表示されなくなりました!)

3️⃣ 先ほどと同じようにbooks/indexページにも記述します!

私は部分テンプレートに記述。(book/_index.html.erb)

4️⃣ 検索バー表示部位の作成


(今回作成したのはタグ検索の部分のみです)

ヘッダーの下にログイン中のみ全部のページで表示していきたいので、、

views/layouts/application.html.erb
<% if user_signed_in? %>
  <%= render 'tagsearches/tagsearch' %>
<% end %>
_tagsearch.html.erb
<div class="serch_form" >
  <table align="center">
    <tr>
      <div class="serch_form">
      <%= form_with url: tagsearches_search_path,method: :get, local: true do |f| %>
      <td><%= f.text_field :content %></td>
      <td><%= f.submit'タグ検索' %></td>
      <% end %>
      </div>
    </tr> 
  </table>  
</div>

5️⃣ 検索結果表示ページの作成

私は、books/_index.html.erbの部分テンプレートを使用。

views/tagsearches/tagsearch.html.erb
<h2><%= @model %>s search for "<%= @word %>"</h2>

<%= render 'books/index', books: @books %>
ちなみに部分テンプレートはこんな感じ
books/_index.html.erb
<table class='table table-hover table-inverse'>
  <thead>
    <tr>
      <th></th>
      <th>Title</th>
      <th>Opinion</th>
      <th>Tag</th>
      <th colspan="3"></th>
    </tr>
  </thead>
  <tbody>
    <% books.each do |book| %>
      <tr>
        <td><%= link_to book.user do %>
          <%= image_tag book.user.get_profile_image(50, 50) %>
          <% end %>
        </td>
        <td><%= link_to book.title,book, class: "book_#{book.id}" %></td>
        <td><%= book.body %></td>
        <td>
          <% if book.category.present? %>
            <%=link_to book.category,tagsearches_search_path(content: book.category)%>
          <% end %>
          </td>
        <td class=<%= "favorite-" + book.id.to_s %> >
            <%= render "favorites/favorite", book: book %>
        </td>
        <td><p>コメント件数:<%= book.post_comments.count %></p></td>
        <td><%= render "books/static_rate", book: book %></td>
      </tr>
    <% end %>
  </tbody>
</table>

🌱参考にさせていただいた記事

https://qiita.com/Auk10/items/c4abe0279429857e9641

https://zenn.dev/airiswim/articles/b680d23314bd3b

この流れで実装できるはずです💡
もし間違っているところなどあれば、コメントで教えてください🙇🏻‍♀️

Discussion