TodoList: 複数の公開情報更新をデータベースに反映 ― 2006年12月24日 09時37分11秒
app/controllers/todo_controllers.rb に新しい関数を作る。update_published と呼ぶことにした。
実は更新を処理する過程で、無効な入力が入ってくる可能性に気が付いた。とりうる値は三つで、古い値と新しい値があるので合計九通りの処理が出来ることになる。しかし、一度公開したのを中止することは出来ても、無かったことには出来ない。NO は YES に移行するのみで、YES になったとは YES と STOPPED を入れ換える事が出来るだけだ。
それ以外の入力が来ても、無視するかユーザにエラーを返すしかない。そうなるとユーザの入力値制限して、ユーザに不当な値を指定できないようにした方が早い。そこで、app/views/todo/_published.rhtml を以下のように変更した。
<%= start_form_tag :action => 'update_published', :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,
if @organization_ids.member?(org.id) then @yes_stopped else @yes_no end,
{ },
{
: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 %>
</table>
<%= submit_tag "Save" %>
<%= end_form_tag %>
organization_id が organization_ids 配列の中にあるか無いかによって初期値を決めるのである。
そして、データベースの更新を app/controllers/todo_controller.rb の update_published 関数の中で行う。
def update_published
@params[:organization].each { | org_id, attr |
top = TodoOrganizationPermission.find(:first,
:conditions=>["todo_id = ? AND organization_id = ?",
@params[:id], org_id]
)
if top == nil
if attr[:published].to_i() == 1 # "NO" to "YES"
top = TodoOrganizationPermission.new
top.update_attribute(:todo_id, @params[:id])
top.update_attribute(:organization_id, org_id)
top.update_attribute(:published, attr[:published])
top.save
end
elsif attr[:published].to_i() != top.published.to_i()
# "YES/STOPPED" is changed to "STOPPED/YES"
top.update_attribute(:published, attr[:published])
end
}
redirect_to :action => 'show', :id => @params[:id]
end
protected
def published
@yes_no = [ ["YES", 1], ["NO", -1] ]
@yes_stopped = [ ["YES", 1], ["STOPPED", 0] ]
@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
@params[:organization]
にて画面で指定されている全ての公開情報が手に入る、これは Hash なので、each で各々を処理するのだ。まず、todo_organization_permissions テーブルに対応する対のレコードがあるかを調べる。それをユーザの入力と照らし合わせて更新する。ユーザの入力とデータベースの値なら更新する必要はない。違った場合は上の条件に従って処理すればいい。
これで、ユーザが Todo の公開情報を更新出来るようになった。
コメント
トラックバック
このエントリのトラックバックURL: http://uyota.asablo.jp/blog/2006/12/24/1045209/tb
※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。
コメントをどうぞ
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。
※なお、送られたコメントはブログの管理者が確認するまで公開されません。