Rails カテゴリタグを追加し検索
要件
- 本の投稿をする際にカテゴリタグを追加できる
- 作成したタグで検索ができる
- 作成したタグのリンクをクリックすると検索ができる
完成
検索結果表示ページ
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ファイル」を追加して対応しましょう。
ちなみに、ターミナルでもカラムを確認できる!
rails runner 'puts モデル名.column_names'
categoryが作成されていることがわかる💪🏻
2.コントローラー作成、バリデーション設定
バリデーション設定
validates :category, presence: true
ストロングパラメータの設定
books_controllerのストロングパラメータに:categoryを追加
private
def book_params
params.require(:book).permit(:title, :body, :profile_image, :star, :category)
end
コントローラーを作成
TagSearchesコントローラーを作成
rails g controller Tagsearches
コントローラーへの記述は以下の通り
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文字
🏋🏻わかりやすかった記事
whereメソッドの使い方まとめ
LILE句の使い方
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ページにも記述
<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️⃣ 検索バー表示部位の作成
(今回作成したのはタグ検索の部分のみです)
ヘッダーの下にログイン中のみ全部のページで表示していきたいので、、
<% if user_signed_in? %>
<%= render 'tagsearches/tagsearch' %>
<% end %>
<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の部分テンプレートを使用。
<h2><%= @model %>s search for "<%= @word %>"</h2>
<%= render 'books/index', books: @books %>
ちなみに部分テンプレートはこんな感じ
<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>
🌱参考にさせていただいた記事
この流れで実装できるはずです💡
もし間違っているところなどあれば、コメントで教えてください🙇🏻♀️
Discussion