6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

accepts_nested_attributes_for メソッド:編集画面不具合の原因は。

Last updated at Posted at 2020-12-07

前回に引き続きaccepts_nested_attributes_for メソッドについての記事です。Ruby on Rails を使っての開発になります。
####結論
「accepts_nested_attributes_for を使うときは、controller の strong parameter に注意。permit の中に関連づけたメソッドの id を追加しておく」という結論になります。

####起きていた現象
Railsで accepts_nested_attributes_for メソッドを使い作成したWebサービスにて。

index、new、show、deleteなどは問題なく行えるが、編集画面(edit, update)での挙動で異常が発生。前回の記事でいうと、編集画面を表示させるたびに、子メソッドの タイトル(title), 記事内容(content), ブログ番号(blog_num)がデーターベースに2重に登録され、同じ記事が2つずつ登録されてしまうのです。

####確認したこと
ヒントを探してターミナルを確認。すると、今回は早速それらしき内容が表示されていました。

Unpermitted parameter: :id

これは、以前の記事(画像アップロードでエラーメッセージの重要性を再認識した話)と同じエラー、つまりstrong parameter で id という要素が許可されていないみたいです。

確かに、strong parmeter をチェックしても、、、

user_controller.rb
  def user_params
    params.require(:user).permit(:name, :address, :age, blogs_attributes: [:title, :content, :blog_num])
  end

:id と言う記述をしていません。

####エラーを修正
不具合が発生しているのが子メソッドなので、strong parameter の小メソッド(blogs_attributes)の中に :id と言う記述を追加します。

user_controller.rb
  def user_params
    params.require(:user).permit(:name, :address, :age, blogs_attributes: [:id, :title, :content, :blog_num])
  end

これで子メソッドの同じ記事が2回ずつ登録される不具合は解消しました。

####不具合の背景
この不具合、accepts_nested_attributes_for メソッドを使う場合に起こりがちらしいのですが、なぜこのような不具合が起きるのか、公式リファレンスの類にははっきりした解説のようなものはありませんでした。

私の調べた限り分かったことは「 accepts_nested_attributes_for を使用した場合、 パラメーターに :id が含まれているかどうかで create アクションか update アクションかが決まるらしい」ということです。

「update アクションの時にはパラメーターに id を含める」と覚えてしまうことで乗り切ろうと思います。

はっきりした原因を解説できるようになったら、またその時に解説記事を。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?