前回作成したサンプルで、複数件の更新はひとまず対応できた。
今回は、選択した行のデータを削除できる機能を追加してみたい。
まずはscaffold。クラスの名前を変えただけで、フィールドは同じ。(nameとprice)
rails g scaffold imp_ramen name:string price:integer rake db:migrate次にroutes.rbの編集。これも前回と同様。画面遷移も同じになる。
match '/imp_ramen/update_all' => 'imp_ramen#update_all' match '/imp_ramen/confirm_all' => 'imp_ramen#confirm_all' match '/imp_ramen/edit_all' => 'imp_ramen#edit_all', as: 'edit_all_imp_raman', :via => :get resources :imp_ramenmodelに新たにdelete_checkというフィールドを追加する。
class ImpRaman < ActiveRecord::Base attr_accessor :delete_check end次にcontroller。index、edit_all、confirm_allは前回から変更なし。
update_allを下記のように編集。
# GET /imp_ramen/update_all def update_all @imp_ramen = session[:imp_ramen] for imp_raman in @imp_ramen if imp_raman.delete_check to_destory_raman = ImpRaman.find(imp_raman.id) to_destory_raman.destroy else imp_raman.save end end session[:imp_ramen] = nil respond_to do |format| format.html { redirect_to imp_ramen_url } format.json { head :no_content } end enddelete_checkがtrueの場合に、該当行のデータのdestroyを実行。
to_destory_ramanに代入し直しているのは、imp_ramanはループ中の配列の要素なので、ここでdestoryするとエラーが発生してしまうため。
DBに反映後は、セッションはもう不要なので、nilを代入してクリア。
indexのviewを指定してレンダリングすると変更が反映されない中途半端な状態で表示されてしまうので、indexのURLへリダイレクトしている。
複数同時更新画面(edit_all)のviewは下記の通り。
<h1>Editing all imp_ramen</h1> <%= form_tag :action => 'confirm_all' do %> <table border="1"> <tr> <th>削除</th> <th>Name</th> <th>Price</th> </tr> <% for imp_raman in @imp_ramen %> <tr> <td> <%= hidden_field_tag("imp_ramen[][id]", imp_raman.id) %> <%= check_box_tag("imp_ramen[][delete_check]", true, imp_raman.delete_check) %> </td> <td> <%= text_field_tag("imp_ramen[][name]", imp_raman.name) %> </td> <td> <%= number_field_tag("imp_ramen[][price]", imp_raman.price) %> </td> </tr> <% end %> </table> <%= submit_tag "入力確認" %> <% end %> <%= link_to 'Back', imp_ramen_path %>check_boxはチェックされている場合のみ値が送信されるので、チェックされていない行があると位置がズレてしまう。
hidden_fieldをcheck_boxの前に持ってくると、位置ズレを防ぐことができる。
check_box_tagでは、3番目の引数(チェックされた場合に送信される値)で明示的にtrueをしておかないと、デフォルトでは"on"という妙な値が送信されるので、controller側で編集のために余計なコードが必要になる。
確認画面(confirm_all)のviewは下記の通り。
<h1>Editing all imp_ramen</h1> <table border="1"> <tr> <th>削除</th> <th>Name</th> <th>Price</th> </tr> <% for imp_raman in @imp_ramen %> <tr> <td> <% if imp_raman.delete_check %> <%= '削除' %> <% end %> </td> <td> <%= imp_raman.name %> </td> <td> <%= imp_raman.price %> </td> </tr> <% end %> </table> <%= form_tag :action => 'update_all' do %> <%= submit_tag "更新" %> <% end %> <%= link_to 'Back', edit_all_imp_raman_path %>delete_checkの値をチェックして、trueであれば「削除」を表示している。
実際の画面遷移の例は以下のようになる。
一覧画面(index)
更新画面(edit_all)
確認画面(confirm_all)
更新後の一覧画面(index)
今回作成したソースコードの参照はこちらから。
https://github.com/torafugu/mytest/tree/master/app/views/imp_ramen
https://github.com/torafugu/mytest/blob/master/app/models/imp_raman.rb
https://github.com/torafugu/mytest/blob/master/app/controllers/imp_ramen_controller.rb
今回参考にさせていただいたブログの記事。
Ruby on Railsあれこれ/複数従業員情報の一括更新
0 件のコメント:
コメントを投稿