#投稿にタグを紐付け〜絞り込みまで
##前提
- 投稿機能実装済
- 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
を追加,空で保存できないように修正する
####boards
とtag
を紐付ける中間テーブルの作成
$ 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_all
でboard
モデルのデータの削除と共に紐付いたタグも削除されるよう記述(複雑な処理でなく、まとめて削除する際効率が良いということでdelete_all使用)
class Tag < ApplicationRecord
has_many :board_tag_relations, dependent: :delete_all
has_many :boards, through: :board_tag_relations
end
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
を許可する指定 []
は配列で渡ってくることを意味
private
def board_params
params.require(:board).permit(:name, :title, :body, tag_ids: [] )
end
ビュー記述
タグフォーム
corection_check_boxs
メソッド使用
第一引数に相手のモデル名_idで関連つける、第2引数にはtagオブジェクトのリストを取得して渡している
第三引数にはチェックボックスのバリューに設定するプロパティ第4引数には各チェックボックスのラベル名としての設定
<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
をループしてタグの数だけタグ名を表示
<% board.tags.each do |tag| %>
<span class="badge badge-primary"><%= tag.name %></span>
<% end %>
rails c
やseed
などを使用して、タグを作成したらブラウザに表示される
タグセレクトボックスを追加してタグに関連付いた投稿を絞り込みをできるようにする
<%= 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
で取得
def index
@boards = params[:tag_id].present? ? Tag.find(params[:tag_id]).boards : Board.all
@boards = @boards.page(params[:page])
end
これでタグの絞り込みが可能です