#初めに
collection_check_boxesというとても便利なものがあると知ったので使ってみました。
例えばカテゴリを選択する際に既に登録されているカテゴリからチェックボックスで選択する場合に使える
#使い方
collection_check_boxesについてはrails guidesで
objectが属するクラスのmethodの既存の戻り値をコレクションにしたcheck_boxタグを返します。
だそうです。
使い方としては
<%= collection_check_boxes(:article, :tag_ids, Tag.all, :id, :name) do |tag| %>
<%= tag.label do %>
<%= tag.check_box %>
<%= tag.text %>
<% end %>
<% end %>
みたいな感じで使えます。
これで既存のタグのチェックボックスが作られます。
#実際に使ってみる
まず
rails new qiita_collection_check_boxes
rails g model article title
rails g model tag name
rails g model article_tags article:references tag:references
rails db:migrate
rails g controller articles
みたいにする
rails routes.rbを
resources :articles
として
articles_controllerを
class ArticlesController < ApplicationController
def index
@articles = Article.all
end
def new
@article = Article.new
end
def create
@article = Article.new(article_params)
if @article.save
redirect_to articles_path
else
render :new
end
end
private
def article_params
params.require(:article).permit(:title, tag_ids: [])
end
end
こんな感じにする。
ここで重要なのがストロングパラメータの
tag_ids: []
のところ
いまいち仕組みが分かっていないんですがcollection_check_boxesでtag_idsを取得してそれが複数の可能性があるから配列にしています。
ただなんでこれで自動的に中間テーブルの作成を行ってくれるのかはわかりません。
ですがとりあえずこれで中間テーブルまで自動的に作成されます。
modelファイルはこんな感じ
class ArticleTag < ApplicationRecord
belongs_to :article
belongs_to :tag
end
class Article < ApplicationRecord
has_many :article_tags
has_many :tags, through: :article_tags
end
class Tag < ApplicationRecord
has_many :article_tags
has_many :articles, through: :article_tags
end
これでOK
後はviewを作るのみ
<%= form_with model: @article, local: true do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= collection_check_boxes(:article, :tag_ids, Tag.all, :id, :name) do |tag| %>
<%= tag.label do %>
<%= tag.check_box %>
<%= tag.text %>
<% end %>
<% end %>
<%= f.submit %>
<% end %>
collection_check_boxesは
objectが属するクラスのmethodの既存の戻り値をコレクションにしたcheck_boxタグを返します。
ということでしたが
Tag.allをしてその一つ一つのid,nameというメソッドの戻り値を取得しています。
tag.labelの中にtag.textと書いていますがこれがtag.nameではうまく動きません。
このあたりもいまいち仕組みが分かってません。
ですがこれで実行すると
こんな感じで既存のタグが出てきてくれます。
おわり