3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsで投稿編集時に予め所属カテゴリにチェックをつける方法

Last updated at Posted at 2020-06-25

多対多の関係のPostとCategoryをもつテーブルに置いて、Post編集時に既存のカテゴリに予めチェックボックスをつける方法。form_with model: @postの形式を使わないと{checked:}オプションを使えないので少しハマった。

前提:多対多のテーブル構成を実現する

以下を参考にテーブル構成してる前提です。ただし投稿のtitleは本記事ではnameになってます。

Railsで投稿とカテゴリの紐付け機能を実装する

collection_check_boxesの引数に{checked:}オプションを追加

前段の多対多のテーブルを作成している前提だと、@post.category_idsで所属カテゴリを配列で取得できるらしい。それに.map(&:to_param) してやることでチェックが付く。この&:to_paramというのはいつも固定で、@postcategory_idsのようにテーブルやモデルの名称によって変わるものではない。

app/views/posts/edit.html.erb
<%= f.label :category, 'カテゴリ' %>
      <%= f.collection_check_boxes(:category_ids, Category.all, :id, :name, { checked: @post.category_ids.map(&:to_param) }) do |category| %> 
        <%= category.label do %>
          <%= category.check_box %>
          <%= category.text %>
        <% end %>
      <% end %>

もしform_with model: @postで「undefined method 'post_path'」とエラーが出る時

form_with model: @post, url: posts_create_path doみたいな書き方をしていると{checked:}オプションは使えない。以下の回答のコメント欄にあるようにresoucesを使わないといけない。
https://teratail.com/questions/200474

本題:最終的なコード

routes.rb
Rails.application.routes.draw do
  resources :posts, only: [:new, :create, :edit, :update]
end

posts_controller.rb
class PostsController < ApplicationController

  def  new
    @post = Post.new
  end

  def create
    @post = Post.create(post_params)
    redirect_to('/posts/index')
  end

  def show
    @post = Post.find(params[:id])
  end

  def edit
    @post = Post.find(params[:id])
  end

  def update
    @post = Post.find(params[:id]).update(post_params)
    redirect_to("/posts/index")
  end

  private

  def post_params
    params.require(:post).permit(:name, category_ids: [])
  end

end
app/views/posts/edit.html.erb
<div class="main posts-index">
  <div class="container">
    <%= form_with model: @post do |f| %>
  
    <p>
      <%= f.label :name, 'name'%>
      <%= f.text_field :name %>
    </p>
  
    <p>
      <%= f.label :category, 'カテゴリ' %>
      <%= f.collection_check_boxes(:category_ids, Category.all, :id, :name, { checked: @post.category_ids.map(&:to_param) }) do |category| %> 
        <%= category.label do %>
          <%= category.check_box %>
          <%= category.text %>
        <% end %>
      <% end %>
    </p>
  
    <%= f.submit '変更を保存' %>
  <% end %>
  </div>
</div>

その他

Railsはマイグレーションファイルの生成やdb:migrateを少しでもミスると、特に本番デプロイ時にDBがおかしくなったりするから気をつけてね。一度でもdb:migrateしたら、もうそのマイグレーションファイルは使えないし、schemaを直接書き換えたりしてもダメだよ。

こちらも参考になりそう👇
【Rails】form_with/form_forについて【入門】

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?