LoginSignup
17
19

More than 5 years have passed since last update.

Railsでhas_and_belongs_to_manyを利用したUIを作成する

Last updated at Posted at 2014-10-10

昨日、has_and_belongs_to_many を利用したモデルを作成しました。
モデルを作ったはいいものの、ビュー/コントローラからの利用方法が分からず、またいろいろと調べたのでメモ。

画面

グループにユーザーを追加するUIを作ってみたので、その手順です。

hbtm_group_edit.PNG

ひな形はscaffold_controllerで作成。

$ rails generate scaffold_controller user
$ rails generate scaffold_controller group

scaffold_controllerではモデルの項目がビューに反映されないので、そこは付け足しました。
以下、この状態からの変更点をメモ。

ビュー

app/views/groups/_form.html.erb
  <div class="field">
    <strong>Users</strong>
    <ul>
    <% @users.each do |user| %>
      <li>
        <label>
          <% checked = user.groups.exists?(@group.id) ? true : false %>
          <%= f.check_box 'user_ids', { :name => 'group[user_ids][]', :checked => checked }, user.id, nil %>
          <%= user.name %>
        </label>
      </li>
    <% end %>
    </ul>
  </div>

入力フォームにユーザー選択のチェックボックスを追加。
:name => 'group[user_ids][]'としてユーザIDを配列で渡します。

コントローラー

app/controllers/groups_controller.rb
  before_action :set_users, only: [:new, :edit]

  private 
    def set_users
      @users = User.all
    end

    def group_params
      p = params.require(:group).permit(:name, :description, :user_ids => [])
      p[:user_ids] = [] if p[:user_ids].nil?
      p
    end

パラメータ取得のメソッドを変更してuser_idsを受け取るようにします。
p[:user_ids] = [] if p[:user_ids].nil?の部分は、チェックボックスがひとつも選択されなかった場合に、すべてのユーザーをグループから削除するために追加してます。

以上。
これだけのことを調べるのに結構かかってしまった・・・

追記

後日試してみたところ、上記の方法は has_many :through のアソシエーションでも使えました。
collection_singular_ids=ids のメソッドが定義されるアソシエーションで使えるのかな?と思います。

Active Recordの関連付け(アソシエーション)

17
19
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
17
19