Railsのscaffoldで作成されるedit画面は、1件のデータしか更新できない。
データの数が多い場合は、1件1件edit画面を開いて更新するのは面倒である。
一覧形式で複数件同時に更新できる画面を作成してみる。
まずはscaffold。
rails g scaffold ramen name:string price:integer rake db:migrateラーメンでramenというクラス名にしてみたのだが、menがmanの複数形として判断されるので、クラスの単数形はramanとなってしまった。
まぁこれはこれで識別しやすいのでこのまま利用する。
次にroutes.rbの編集。以下を追加した。
match '/ramen/update_all' => 'ramen#update_all' match '/ramen/confirm_all' => 'ramen#confirm_all' match '/ramen/edit_all' => 'ramen#edit_all', as: 'edit_all_raman', :via => :get resources :ramen画面遷移としては、
という流れになる。
次にcontrollerを編集する。
# GET /ramen
# GET /ramen.json
def index
@ramen = Raman.all
session[:ramen] = @ramen
respond_to do |format|
format.html # index.html.erb
format.json { render json: @ramen }
end
end
まず一覧画面(index)の検索結果をセッション(session[:ramen])に入れておく。複数同時更新画面(edit_all)では、DBからではなく、セッションから取得する。
# GET /ramen/edit_all
def edit_all
@ramen = session[:ramen]
end
セッションを使う理由は、確認画面(confirm_all)から更新画面(edit_all)に戻った場合に変更部分を維持するため。確認画面(confirm_all)では、画面から送られたパラメータの値でRamanクラスを編集して再度セッションに格納している。
# GET /ramen/confirm_all
def confirm_all
@ramen = Array.new
for raman in params[:ramen]
updated_raman = Raman.find(raman["id"])
updated_raman.update_attributes(raman)
@ramen << updated_raman
end
session[:ramen] = @ramen
end
@ramenはRamanクラスの配列で、モデルで定義している型と同じではないために、パラメータの値をそのままクラスとして利用することができずに、ちょっと面倒なことをしている。更新処理(update_all)では、セッションから値を取得してDBにsaveするのみ。
# GET /ramen/update_all
def update_all
@ramen = session[:ramen]
for raman in @ramen
raman.save
end
render action: "index"
end
複数同時更新画面(edit_all)のviewは下記の通り。<h1>Editing all ramen</h1>
<%= form_tag :action => 'confirm_all' do %>
<table border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
</tr>
<% for raman in @ramen %>
<tr>
<td>
<%= raman.id %>
<%= hidden_field_tag("ramen[][id]", raman.id) %>
</td>
<td>
<%= text_field_tag("ramen[][name]", raman.name) %>
</td>
<td>
<%= number_field_tag("ramen[][price]", raman.price) %>
</td>
</tr>
<% end %>
</table>
<%= submit_tag "入力確認" %>
<% end %>
<%= link_to 'Back', ramen_path %>
@ramenがRamanクラスの配列なので、ループを回して一つづつ取り出して、inputタグを作成している。"ramen[][XXXX]"と記述すると、ramenという名前のパラメータの配列の項目名として扱ってくれるようだ。
確認画面(confirm_all)のviewは下記の通り。
<h1>Editing all ramen</h1>
<table border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
</tr>
<% for raman in @ramen %>
<tr>
<td>
<%= raman.id %>
</td>
<td>
<%= raman.name %>
</td>
<td>
<%= raman.price %>
</td>
</tr>
<% end %>
</table>
<%= form_tag :action => 'update_all' do %>
<%= submit_tag "更新" %>
<% end %>
<%= link_to 'Back', edit_all_raman_path %>
controllerが既にセッションに値を確認しているので、ここでは単純に表示するだけ。実際の画面遷移の例は以下のようになる。
一覧画面(index)
https://github.com/torafugu/mytest/tree/master/app/views/ramen
https://github.com/torafugu/mytest/blob/master/app/models/raman.rb
https://github.com/torafugu/mytest/blob/master/app/controllers/ramen_controller.rb
実際に動くサンプルはこちらから。(heroku上のサイト)
http://ancient-savannah-6605.herokuapp.com/ramen
今回参考にさせていただいたブログの記事。
Rails のフォームで配列形式のデータを扱う方法
http://webos-goodies.jp/archives/51387214.html
Ruby on Railsあれこれ/複数従業員情報の一括更新
http://winter-tail.sakura.ne.jp/pukiwiki/index.php?Ruby%20on%20Rails%A4%A2%A4%EC%A4%B3%A4%EC%2F%CA%A3%BF%F4%BD%BE%B6%C8%B0%F7%BE%F0%CA%F3%A4%CE%B0%EC%B3%E7%B9%B9%BF%B7





0 件のコメント:
コメントを投稿