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 件のコメント:
コメントを投稿