バーテンダーエンジニア

元フレアバーテンダーからエンジニアに転職。未経験からのエンジニア転職経験談・実務で感じたこと・個人開発で学んだ内容・日常話などマイペースに発信していきます。仕事ではphp、Laravel、Vue.js、Angular辺りを触ってます。趣味は筋トレ!!ソムリエの資格も持ってます^^

Railsで関連モデルを同時に更新する方法

はじめに

このブログは、下記ブログの続編になります。

ykichannel.hatenablog.jp こちらの記事では、userモデルとprofileモデルを1対1で関連づける方法を紹介しました。
今回は、関連づけたモデルを同時に更新する方法を備忘録としてまとめておきたいと思います。

前提条件

userモデルとprofileモデルは既に1対1の関連付けがされている事とします。(関連づけの方法がわからない場合は過去記事を参照ください)
開発環境は以下の通りです。

Mac OS Mojave 10.14.5
Ruby 2.5.3
Rails 5.2.3


accepts_nested_attributes_forを追加する

Railsが標準で提供している、ActiveRecordのメソッドの一つであるaccepts_nested_attributes_forを追加していきます。
これはモデル同士が関連付けられている時に、ネストさせることで一度にまとめてレコードの更新することを可能にします。

-user.rb
class User < ApplicationRecord
  has_one :profile, dependent: :destroy  
  accepts_nested_attributes_for :profile  
end  


フォームを作成する

フォームの作成には fields_forを利用する事でform_with内で異なるモデルを編集できるようにしていきます。

-views/users/edit.html.erb
<%= form_with model: @user, local: true do |f| %>
    <div class='form-group'>
      <%= f.label :name %>
      <%= f.text_field :name %>
    </div>
    <%= f.fields_for :profile, @user.profile || Profile.new do |pf| %>
      <div class='form-group'>
        <%= pf.label :user_profile %>
        <%= pf.text_area :user_profile %>
      </div>
    <% end %>
    <%= f.submit '更新する %>
  <% end %>


コントローラーの実装

ストロングパラメータを以下のように設定することでuser_profileの入力を渡すことが可能になります。

-controllers/users_controller.rb
  def user_update_params
      params.require(:user).permit(:name, profile_attributes: [:user_profile])
  end

あとは通常のアップデートアクションを実装することで同時に関連モデルuser.rbとprofile.rbを更新することが可能になります。