1
0

More than 1 year has passed since last update.

[Rails]本にカテゴリタグを追加し検索する

Posted at

行いたいこと

  • 本の投稿時にカテゴリタグを追加する
  • カテゴリタグで検索が出来る

環境

  • Ruby3.1.2
  • Rails6.1.7
  • device、bootstrap導入済み
  • Bookモデル作成済み

1.カラムの追加

Bookモデルにタグを保存するために新しくカラムtagを作成

# rails g migration add追加したいカラム名To追加したいモデル名 追加したいカラム名:データ型
  rails g migration addTagToBook tag:string
作成日_add_tag_to_book.rb
class AddTagToBook < ActiveRecord::Migration[6.1]
  def change
    add_column :books, :tag, :string
  end
end
$ rails db:migrate

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

バリデーション、ストロングパラメータの設定

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

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

books_controller.rb
  private

  def book_params
    params.require(:book).permit(:title,:body,:rating,:tag)#tagを追加
  end

TagSearchesコントローラーを作成

$ rails g controller TagSearches

コントローラーへの記述は以下の通り
今回は部分一致で検索を実施
@modelはresultのviewを他から流用しており、そこで@modelを使用しているため指定
searchとしての処理には不必要であり、後述のviewで使用しないなら削除してOK

layouts/_tag_search.html.rb
class TagSearchesController < ApplicationController
  def search
    @model = Book #search機能とは関係なし
    @word = params[:word]
    @books = Book.where("tag LIKE?","%#{@word}%")
    render "searches/result"
  end
end

3.viewページの作成

投稿フォームへの追加

tagを追加するためのtext_fieldを作成

views/books/_form.html.erb
  <div class="form-group">
    <%= f.label :Tag %>
    <%= f.text_field :tag, class: 'form-control book_tag' %>
  </div>

タグ検索用の検索ボックスの作成

views/layouts/_tag_search.html.erb
<% if user_signed_in? %>
  <div class="search_form">
    <%= form_with url: tag_search_path, local: true,method: :get do |f| %>
      < %= f.text_field :word %>
      <%= f.submit "タグ検索" %>
    <% end %>
  </div>
<% end %>

検索結果の表示

今回他で作成した検索結果表示ページを流用
book.tagで保存されたタグを呼び出す

views/searches/_result.erb
<h2><%= @model %>s search for "<%= @word %>"</h2>
# Books search for "<%= @word %>"と記載すれば@model不要

<table class="table table-hover table-inverse">
       〜省略〜
    <thead>
      <tr>
        <th></th>
        <th>Title</th>
        <th>Opinion</th>
        <th>Tag</th>
      </tr>
    </thead>
    <% @books.each do |book| %>
    <tbody>
      <tr>
        <td><%= image_tag book.user.get_profile_image, size:'50x50' %></td>
        <td><%= book.title %></td>
        <td><%= book.body %></td>
        <td><%= book.tag %></td> #追加!
        <td><%= render "favorites/nice", book: book %></td>
        <td>コメント数:<%= book.book_comments.count %></td>
        <td class ="px-0"><%= render "books/rating", book: book %></td>
      </tr>
    </tbody>
    <% end %>
  <% end %>
</table>

またindexにも同様に <%= book.tag %> で表示

views/books/_index.erb
 <% books.each do |book| %>
      <tr>
        <td><%= link_to(book.user) do %>
          <%= image_tag book.user.get_profile_image, size:'50x50' %>
          <% end %>
        </td>
        <td class ="px-0"><%= link_to book.title,book %></td>
        <td><%= book.body %></td>
        <td><%= book.tag  %></td> #追加
        <td id="js-book_favorite_<%= book.id %>">

完成!(今回作成したのはタグ検索の部分のみ)
スクリーンショット.png

応用

タグにリンクを付与し、クリックすると、そのタグ名で検索を行う

上記記事にも投稿しましたが、link_to〜_path( )の( )に値を設定することで、任意の値を一緒に送信することが出来る
これを活用し

.rb
<%= link_to book.tag, tag_search_path(word: book.tag) %>

とリンクを作成することで、送信時一緒に:wordとしてbook.tagが送られる

投稿済みの本に設定してあるタグから検索する方法

f.text_fieldを削除し、下記のコードを追加

_tag_searches_controller.rb
#〜省略〜
<%= f.text_field :word %> #削除
#下2行追加
<% tag = Book.select(:tag).distinct %> 
<%= f.collection_select(:word, tag, :tag, :tag) %>
#〜省略〜

tag = Book.select(:tag).distinct
本の投稿からtagカラムだけを抜き出し、distinctで重複を削除
distinctを使用しないと下記のように全件表示される(空欄はtag未設定の投稿)
スクリーンショット.png
f.collection_select(:word, tag, :id, :tag)
collection_selectはRailsドキュメントを参照すると
Railsドキュメント(collection_select)

f.collection_select(メソッド名, 要素の配列, value属性の項目, テキストの項目, オプション={}, HTML属性={} or イベント属性={})

とある。つまり

  • 第1引数:word メソッド名。送信したい項目名と言い換えればわかりやすいか
  • 第2引数tag参照するデータ。今回はひとつ上に書いたtag = Book.〜のtagを指定。Book.all等も指定できる
  • 第3引数:tag第2引数のデータの中で、送信するデータのカラムを指定。tagカラムの内容を送りたいので:tag
  • 第4引数:tagテキストの項目。第2引数のデータの内実際に選択肢として表示したい物。tagカラムの中身を表示したいので:tag

※この場合下記の様に、コントローラーは完全一致で検索するように修正したほうが的確

tag_search_controller.rb
@books = Book.where(tag: @word)

以上で投稿された本のタグで検索が行えるようになる
スクリーンショット 2022-12-09 18.44.41.png

1
0
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
1
0