Railsのアソシエーションと複数登録 ~修正画面~
前回の続き
残りの修正画面を作成する
Editの作成
before_action :set_profile, only: [:edit, :confirm, :update] def edit end def set_profile @profile = Profile.find(current_user.profile.id) if current_user.profile.present? end
editを追加する。
@profileのセットは edit,confirm,updateの3箇所で必要なので、まとめてbefore_actionに設定。
ただしconfirmはnewから経由した場合は不要なので、current_userのprofileがある場合のみ。
Confirmの修正
NewとEditの両方から遷移するので、if分で分岐させる。
def confirm if @profile @profile.assign_attributes(profile_params) render :edit if @profile.invalid? else @profile = current_user.build_profile(profile_params) render :new if @profile.invalid? end end
newの場合はまだレコードができていないので、current_user.build_で良いが、Editの場合既にレコードが存在するので使えない。
この場合は.assign_attributes
を使いparamsを仮セット出来る。
ただし、このままだと一点があり、deleteしたはずのデータがconfirm画面に表示されてしまう。
(勝手に消されても困るが・・)
# game_careersに4レコード登録した状態でEdit画面でレコードid14と15を # deleteボタンで削除し、確認画面へ遷移する GameCareer Load (0.5ms) SELECT "game_careers".* FROM "game_careers" WHERE "game_careers"."profile_id" = $1 [["profile_id", 12]] => [#<GameCareer:0x00007f8df1ca5a68 id: 12, profile_id: 12, name: "test1">, #<GameCareer:0x00007f8df1ca5298 id: 13, profile_id: 12, name: "test2">, #<GameCareer:0x00007f8df1ca4870 id: 14, profile_id: 12, name: "test3">, #<GameCareer:0x00007f8df1ca4050 id: 15, profile_id: 12, name: "test4">] # Confirm画面のprams profile_params[:game_careers_attributes] => <ActionController::Parameters{ "0"=><ActionController::Parameters {"id"=>"12", "name"=>"test1"} permitted: true>, "1"=><ActionController::Parameters {"id"=>"13", "name"=>"test2"} permitted: true>, "2"=><ActionController::Parameters {"id"=>"14", "name"=>"test3", "_destroy"=>"1"} permitted: true>, "3"=><ActionController::Parameters {"id"=>"15", "name"=>"test4", "_destroy"=>"1"} permitted: true> } permitted: true>
そこでView側を修正。_destroy
がtrueの場合は確認画面で表示しないようにする。
<% @profile.game_careers.each do |c| %> # _destoryがtrueの場合は表示しない <%= c.name unless c._destroy %> <% end %>
確認画面には戻るボタンが必要なので、それも追加する。
link_to :back
(ブラウザのBack)だと、validationが絡んだ場合にエラーを起こすので、ちゃんとsubmitする。
方法は色々あるが、今回はsubmitボタンの名前を使って分岐する仕組みにする。
クリックしたsubmitの名前が[戻る]かどうかチェックするメソッドを作成。
def submit_back? params[:commit] == I18n.t('helpers.submit.back') end
それをcreateとupdateに組み込む。
def create @profile = current_user.build_profile(profile_params) if !submit_back? && @profile.valid? @profile.save! redirect_to root_path else render :new end end def update @profile.assign_attributes(profile_params) if !submit_back? && @profile.valid? @profile.save! redirect_to root_path else render :edit end end
こうすることで、ちゃんと値を渡しつつ確認画面から戻る事ができる。
基本的な登録画面が完成したので、次は必要なバリデーションを実装する。