Railsでリストにチェックボックスを使う。

1対多の関係のテーブル、例えば、groupsとusersがある時、
groupsのshow.html.erbの中で、usersの全候補を表示して、groupに属するuserを選択する様な画面が作りたい。

その場合、modelでは、

class Group < ActiveRecord::Base
  has_many :message, :through => :transmission
  has_many :user
  has_many :transmission  
end

class User < ActiveRecord::Base
  belongs_to :group
end

として、1対多の関係を定義しておく。

更に、groups_controller.rbで

  def show
    @group = Group.find(params[:id])
    @users = User.all

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @group }
    end
  end

として、@group以外に、@usersに全ユーザを取り込んでおく。
これでデータを取り込む部分は出来たので、次は表示部分

groups/show.html.erbでは、userのリスト用テンプレート(users/_user.html.erb)を読み込む指示をする。

<p>
  <b>Name:</b>
  <%=h @group.name %>
</p>
<table>
	<% if @group.message %>
 	    <% for aa in @group.message %>
		<tr>
		</tr><td><%=h aa.title %></td><td><%=h aa.comment %></td>
		</tr>
	    <% end %>
	<% end %>
</table>

User List!<br>
<table>
<%= render "users/user",
           :collection => @users %>
</table>

<%= link_to 'Edit', edit_group_path(@group) %> |
<%= link_to 'Back', groups_path %>

として、テンプレートを_user.html.erbに

<table>
  <tr>
    <th>Name</th>
    <th>Email</th>
    <th>Group_id</th>
    <th>G-name</th>
  </tr>
  <% @num = 0 %>
  <% @users.each do |user| %>
  <tr>
  	<% @num = @num +1 %>
    <td><%=h user.name %></td>
    <td><%=h user.email %></td>
	<% @checked = false %>
	<% @checked = true if user.group_id == @group.id %>
    <td><%=h @checked %>:<%=h user.group_id %><%= check_box_tag("active[ #{@num.to_s} ]",'true', @checked) %></td>
    <td><%= link_to 'Show', user %></td>
    <td><%= link_to 'Edit', edit_user_path(user) %></td>
    <td><%= link_to 'Destroy', user, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
  <% end %>
</table>

とする。
悩んだのはcheck_box_tagに与えるパラメータ部分で、チェックボックス名は"checkbox名[#{カウント用の変数}]"とした。
user.idを直接使っても良かったかも知れないが、必ずしも要素数とは限らないので。
また、呼び出す側も

<%= render :partial => "users/user",
           :collection => @users %>

とすると、user件数分を2重でループする形になってしまった。つまり呼び出し側でuser数分ループして、呼び出された_user.html.erb側でもuser数分ループしてしまう。

<%= render :partial => "users/user" %>

とすると、呼び出し側のループがなくなって、テンプレート側だけループするので、こちらでもOK。
でもやっぱりpartialの意味が今ひとつ不明。

逆に、呼び出し側でループして、テンプレート側では、パラメータで各要素を受け取って動く方法がないか考えてみた。

<%= render :partial => "users/user" , :collection => @users%>

として、@usersの要素数分のループが回るはずだが、そのとき取り出したUserオブジェクトをどうしたら_user.html.erbに渡せるかが不明で断念。

この辺り、:partialの意味が分かっていないから、何となく”当てずっぽうで、動いたから良いか”って感じだ。(良くはないのだが・・・)