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の意味が分かっていないから、何となく”当てずっぽうで、動いたから良いか”って感じだ。(良くはないのだが・・・)