TodoList: 公開状態の一括更新の情報取得2006年12月23日 11時34分47秒

さて、公開情報を更新する方法が必要だ。まず、app/views/todo/show.rhtml に作った物をパーシャルにして、app/views/todo/edit.rhtml からも表示出来るようにする。

app/views/todo/show.rhtml の中身を app/views/todo/_published.rthml に移す。


% cat app/views/todo/show.rhtml
<% for column in Todo.content_columns %>
<p>
  <b><%= column.human_name %>:</b> <%=h @todo.send(column.name) %>
</p>
<% end %>

<%= render :partial => 'published' %>

<%= link_to 'Edit', :action => 'edit', :id => @todo %> |
<%= link_to 'Back', :action => 'list' %>

show.rhtml は上記のように簡単になった。

以前は表示するだけで良かったが、今度は入力を受け付けなければならない。一つのページ内の情報を一括更新する必要がある。Four Days on Rails を日本語訳の最後のページに参考になる例が載っている。

また、select formで複数選択したいを参考に name 等の変更を試みた。

これらを元に、最初に以下の app/views/todo/_published.rhtml を作った。


% cat app/views/todo/_published.rhtml
<%= start_form_tag :action => 'show', :id => @todo %>
<table>
  <tr>
  <% for column in Organization.content_columns %>
    <th><%= column.human_name %></th>
  <% end %>
   <th>Published-to</th>
  </tr>
<% for org in Organization.find_all() %>
  <tr>
  <% for column in Organization.content_columns %>
    <td><%= org.send(column.name) %></td>
  <% end %>
    <td><%=
      if @organization_ids.member?(org.id)
      then
        if @published_organizations[
          @organization_ids.index(org.id)]['published'] != 0
        then
          "YES"
        else
          "STOPPED"
        end
      else
        "NO"
      end %></td>
    <td>
      <%= select :organization, :id,
       [ ["YES", 1], ["NO", -1], ["STOPPED", 0] ],
       { },
       { :selected =>
          if @organization_ids.member?(org.id)
          then
            if @published_organizations[
              @organization_ids.index(org.id)]['published'] != 0
            then
              1
            else
              0
            end
          else
            -1
          end,
         :name => "organization[" + org.id.to_s() + "][published]" } %>
    </td>
  </tr>
<% end %>

<%= submit_tag "Save" %>
<%= end_form_tag %>

select を使って、プルダウンメニューを作っている以外は、show.rhtml でやったこととほとんど同じである。:name を利用して、 organization の配列を指定する。:selected の部分が冗長になってしまったが、今はこのままでよい。加えて、今回は実験用に show.rhtml に飛ぶように、start_form_tag で指定した。show.rhtml の中からの方が <%= @params.inspect %> が使いやすいからである。もし、controller 内で :redirect_to => { :action => :show } 等とやると、show.rhtml に戻って来るときには @params の内容が失われる為だ。

YES に 1 を、STOPPED に 0 を割り当てた。published フィールドに利用する値である。そのため、NO にはあえて、-1 を使った。NO の時はテーブルにデータが存在しない。

それに対応するように app/controllers/todo_controllers.rb も変更した。


  def show
    published()
    @todo = Todo.find(params[:id])
  end

  def edit
    published()
    @todo = Todo.find(params[:id])
  end

  protected
    def published
      @published_organizations =
        TodoOrganizationPermission.find(:all,
          :conditions=>["todo_id=?", params[:id]])
        #TodoOrganizationPermission.find_all("todo_id = " + params[:id])
      @organization_ids = @published_organizations.map { |o| o.organization_id }
    end

show 関数でやっていた作業を publishd 関数に移し、edit 関数と show 関数から呼び出す。

前回次回