LoginSignup
1
2

More than 1 year has passed since last update.

【Rails】Tag機能 

Posted at

投稿にタグを紐付け〜絞り込みまで

前提

  • 投稿機能実装済
  • bootstrap使用

実装

多対多の関係なので中間テーブルを用意

まずtagモデル作成

ターミナル
$ rails g model tag name:string
class CreateTags < ActiveRecord::Migration[5.0]
  def change
    create_table :tags do |t|
      t.string :name, null: false

      t.timestamps
    end
  end
end

null:falseを追加,空で保存できないように修正する

boardstagを紐付ける中間テーブルの作成

ターミナル
$ rails g model board_tag_relation board:references tag:references
class CreateBoardTagRelations < ActiveRecord::Migration[5.0]
  def change
    create_table :board_tag_relations do |t|
      t.references :board, foreign_key: true
      t.references :tag, foreign_key: true

      t.timestamps
    end
  end
end
ターミナル
rails db:migrate

アソシエーション

throughで中間テーブルを経由して掲示板との関連付け
※複数形
dependent: :delete_allboardモデルのデータの削除と共に紐付いたタグも削除されるよう記述(複雑な処理でなく、まとめて削除する際効率が良いということでdelete_all使用)

app/models/tag.rb
class Tag < ApplicationRecord
  has_many :board_tag_relations, dependent: :delete_all
  has_many :boards, through: :board_tag_relations
end
app/models/board.rb
class Board < ApplicationRecord
  has_many :comments, dependent: :delete_all
  has_many :board_tag_relations, dependent: :delete_all
  has_many :tags, through: :board_tag_relations
end

ストロングパラメーターにtag_idsを忘れず記述

ビューのチェックボックスに指定するtag_idsを許可する指定 []は配列で渡ってくることを意味

app/controllers/boards/controller.erb
private

   def board_params
      params.require(:board).permit(:name, :title, :body, tag_ids: [] )
   end

ビュー記述

タグフォーム
corection_check_boxsメソッド使用
第一引数に相手のモデル名_idで関連つける、第2引数にはtagオブジェクトのリストを取得して渡している
第三引数にはチェックボックスのバリューに設定するプロパティ第4引数には各チェックボックスのラベル名としての設定

app/views/boards/_form.html.erb
<div class="form-group">
    <span>タグ</span>
    <%= f.collection_check_boxes(:tag_ids, Tag.all, :id, :name) do |tag| %>
      <div class="form-check">
        <%= tag.label class: 'form-check-label' do %>
          <%= tag.check_box class: 'form-check-input' %>
          <%= tag.text %>
        <% end %>
      </div>
    <% end %>
  </div>

board.tagsをループしてタグの数だけタグ名を表示

app/views/boards/_board.html.erb
<% board.tags.each do |tag| %>
      <span class="badge badge-primary"><%= tag.name %></span>
    <% end %>

rails cseedなどを使用して、タグを作成したらブラウザに表示される

タグセレクトボックスを追加してタグに関連付いた投稿を絞り込みをできるようにする

app/views/boards/index.html.erb
<%= form_with url: boards_path, method: :get, class: 'boards__searchForm' do %>
      <%= select_tag :tag_id,
                      options_from_collection_for_select(Tag.all, :id, :name, params[:tag_id]),
                      {
                        prompt: 'タグで絞り込み',
                        class: 'form-control boards__select',
                        onchange: 'submit(this.form);'
                      } 
      %>
    <% end %>

 コントローラ記述

タグidがあった場合にはタグidから検索できるようにして、タグに紐付くリストを取得
タグidが渡されなければ Board.allで取得

app/controllers/boards_controller.rb
def index
      @boards = params[:tag_id].present? ? Tag.find(params[:tag_id]).boards : Board.all
      @boards = @boards.page(params[:page])
   end

これでタグの絞り込みが可能です

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