0

私は次のような協会を持っています:

class Contact
  has_many :addresses
  has_many :email_addresses
  has_many :phone_numbers
end

saveすべてのレコード (住所、電子メール、電話番号) を 1 つのステートメントに保存したいと考えています。そのために、次のコードを書きました。

contact = Contact.new(contact_params)
contact.addresses.build(address_params1)
contact.addresses.build(address_params2)
contact.email_addresses.build(email_params1)
contact.email_addresses.build(email_params2)
contact.phone_numbers.build(phone_params1)
contact.phone_numbers.build(phone_params2)
contact.save

連絡先は保存されますが、他のレコードは保存されません。ここで何が欠けていますか?

注: データを保存するためにフォームを使用していません。データをインポートしています。

4

2 に答える 2

0

モデルを追加validates_associatedしてから確認してくださいcontact

validates_associated :addresses, :email_addresses, :phone_numbers
于 2013-08-02T11:54:28.017 に答える
0

まず、私の意見では、それはできません。

  • アドレスを保存したい場合は、アドレスごとに contact_id が必要です。
  • また、連絡先を保存すると、Rails は最初に連絡先とすべてのサブオブジェクトを検証します。これは contact.valid?、レコードを保存する前に真でなければならないことを意味します。
  • contact は db に保存する前に id を持っていないため、どのアドレスの contact_id も空です。したがって、新しい連絡先とそのサブオブジェクトを同時に 作成contact.valid?する必要がある限り、常に false になります。
  • 要約すると、レールの手順は次のとおりです。
    1. 連絡先自体を検証し、成功しました!(メモ: メモを保存しました)
    2. 各 contact.addresses のアドレスを検証します。contact_id が指定されていません。失敗します。

第二に、あなたの問題についての私の提案

「連絡先は保存されますが、他のレコードは保存されません」という問題については、サブオブジェクトを保存することをレールに伝える必要があります(以下に示すように)。そうしないと、レールは他のオブジェクトを無視します。ただし、これを行ったとしても、上で説明した問題も発生します。

#contact.rb
accepts_nested_attributes_for :addresses
...

私の提案: トランザクションを使用できます。

  1. 連絡先を作成する
  2. すべてのサブオブジェクトを構築
  3. 連絡先をもう一度保存する

コードサンプル:

#contacts_controller.rb
Contact.transaction do
  contact = Contact.new(contact_params)
  contact.addresses.build(address_params)
  ...
  contact.save
end
于 2013-11-19T00:52:54.143 に答える