LoginSignup
141
161

More than 5 years have passed since last update.

Rails4でcollection_check_boxesを使って、多対多の関連をチェックボックスで設定する

Last updated at Posted at 2014-06-12

多対多の関連するフォームの作り方

Rails4で 1対多、多対多関連しているときのフォームを作るなら、Nested Form Gemが便利
最初に見つけた多対多の関連フォームの作成サンプルです。
nested form gemを使ったサンプルですが、やりたい事とちょっと違いました。

多対多の関連をチェックボックスで設定したい

Rails3の頃のやり方もちらほら見つかりました。
Rails3でhas_many throughな関連をcheckboxで登録する
(sanojimaruの若大将は元気かな・・・)

Rails4でのやり方は?

その後、いろいろ調べていくと、Rails4ではcollection_check_boxesっていうヘルパーメソッドが増えているという事がわかりました。
今回はこれを使ってやってみます。

collection_check_boxesを使って、関連フォームを作成する

scaffoldでMVCを作成する

適当なサンプルとして、PostとAuthorを作って、それに関連するAuthorPostを作ってみます。
サンプルなので、scaffoldを使っていきます。
コンソールで、次を入力します。
author_postはmodelだけでもいいです。

rails g scaffold post title:string
rails g scaffold author name:string
rails g scaffold author_post post:references author:references

モデルに関連を設定する

post.rbとauthor.rbをこんな感じに編集しましょう。

app/models/post.rb
class Post < ActiveRecord::Base
  has_many :author_posts
  has_many :authors, :through => :author_posts
end
app/models/author.rb
class Author < ActiveRecord::Base
  has_many :author_posts
  has_many :posts, :through => :author_posts
end

ビューにチェックボックスを表示する

postのフォームにauthorのチェックボックスを表示するようにします。

app/view/posts/_form.html.erb

  ...

  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :authors %><br />
    <%= collection_check_boxes(:post, :author_ids, Author.all, :id, :name) do |b| %>
      <%= b.label { b.check_box + b.text } %>
    <% end %>
  </div>

  ...

動きを確認してみる

マイグレーションをして、サーバーを起動してみます。

rake db:migrate
rails s

http://localhost:3000/authors
ここから適当にいくつかauthorを作成しておきましょう。
スクリーンショット 2014-06-12 23.01.07.png

その上で、postの作成画面を見てみます。
http://localhost:3000/posts/new
スクリーンショット 2014-06-12 23.02.19.png

追加した、authorがチェックボックスになって、表示されていますね。
(ちなみに、この段階では、チェックボックスの情報が保存されません。)

チェックボックスの情報が関連情報として保存されるようにする

いよいよ最後です。
チェックボックスの情報がAuthorPostとして保存されるようにしましょう。

app/controllers/posts_controller.rb
class PostsController < ApplicationController

    ...

    def post_params
      params.require(:post).permit(:title, {:author_ids => []})
    end

    ...

end

どうでしょう?
無事こんな感じで保存されましたか?
スクリーンショット 2014-06-12 23.08.42.png

最後に

作成したコードを公開しておきます。
https://github.com/hamichamp/collection_check_boxes_sample

141
161
1

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
141
161