strong_parametersには:idも追加しよう。

ちょっとハマってたのでメモ書き。rails4。
UserとAddressテーブルを作っていたとして、以下のような関係だとする。

class User < ActiveRecord::Base
  has_one :address, inverse_of: :user
  accepts_nested_attributes_for :address
end
class Address < ActiveRecord::Base
  belongs_to :user, inverse_of: :address
  validates :pref, presence: true, on: :update
  validates :city, presence: true, on: :update
  validates :section, presence: true, on: :update
end

ユーザー情報を更新するときに住所も更新したいので、accepts_nested_attributes_forを設定してある。そうなると、strong_parameterの設定であるが、以下のようだとする。

class UsersController < ApplicationController
  private
    def user_params
      params.require(:user).permit(
        :email,
        :password,
        :password_confirmation,
        {address_attributes: [
          :pref,
          :city,
          :section
        ]}
      )
    end
end

まぁこんな感じでやって、動いていたので大丈夫だと思っていたのだが、編集時に必須にしているpref, city, sectionが空でも素通りされてしまった…。フォームの表示上では必須マークも出ているので何が間違っているのかわからなかった。動作を見てみると、addressの行が毎回削除されて新しい行ができていた。なるほど、これではon: :udateが機能することはないということか…。ではどうすればいいのか?をググっていたら、見つかった。

Can’t update my nested model form for has_one association

address_attributesに:idを追加しろ、だそうだ。

class UsersController < ApplicationController
  private
    def user_params
      params.require(:user).permit(
        :email,
        :password,
        :password_confirmation,
        {address_attributes: [
          :id,
          :pref,
          :city,
          :section
        ]}
      )
    end
end

追加したところ、ちゃんとon: :updateが機能するようになった。


タグ Ruby on Rails | パーマリンク.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です