0
0

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 1 year has passed since last update.

【Rails】モデル同士の関連付け「親モデルのフォームから子モデルの属性を同時に作成・更新・削除する場合」

Posted at

_attributesaccepts_nested_attributes_for

accepts_nested_attributes_forメソッドを親モデルに追加することで、親モデルの作成や更新時に、関連する子モデルも同時に作成や更新することができる。
一方、_attributesはストロングパラメータ内で使用され、親モデルとともに子モデルの属性を許可するために使用される。

したがって、親モデルと子モデルの関連を扱い、同時に子モデルの属性を作成や更新したい場合、_attributesaccepts_nested_attributes_forメソッドをセットで使用するのが一般的。

dependent: :destroyオプション

has_manyの関連付けに加えて使用するオプション。
親オブジェクトが削除されると、関連する子オブジェクトも自動的に削除されるようになる。
関連付けをしているにも関わらず、このオプションを付けずに親の削除をしようとするとエラーになる。

allow_destroy: trueオプション

accepts_nested_attributes_forに加えて使用するオプション。
(②のdependent: :destroy は親レコードが削除されたときに、自動的に子レコードも削除するオプション。
しかし、このオプションでは親レコードと子レコードを個別に編集・削除する場合には対応できない。親レコードが削除された場合のみ、子レコードも削除されることになる。)

一方で、allow_destroy: true は、親レコードを更新する際に、子レコードを編集・削除することができるオプション。
親レコードが削除されることなく、子レコードを編集・削除することが可能になる。
(例えば、親レコードを更新する際に、子レコードを追加・削除・変更することができる。)

結論

総括すると、has_many :barcodetagsだけでも関連付けの意味があるが、親モデルのフォームから子モデルの属性を同時に扱う場合には、_attributesaccepts_nested_attributes_forメソッドも使用する必要がある。
また、場合によっては、allow_destroy: trueを使用して、子要素のみの編集・削除も可能にする必要がある。

コード例

親モデルのコントローラー(tagsテーブルのnameカラムに書き込みできるように処理を追加)

def recipe_params
  params.require(:recipe).permit(:title, :content, :time, :price, :calorie, :image,
                                 tags_attributes: [:name])
end

子モデル

class Recipe < ApplicationRecord
  belongs_to :user
  has_many :tags, dependent: :destroy

  accepts_nested_attributes_for :tags, allow_destroy: true
end
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?