2

Companyモデルにポリモーフィックな関連付け(contact_details)があり、親モデルを検証したいと思います。注:親モデルでaccepts_nested_attributes_forを使用しています。

基本的なルール:

会社には少なくとも1台の電話が必要です(電話はcontact_detailの一種です)

問題:

親オブジェクトの検証後に子オブジェクトのdestroyを呼び出すaccepts_nested_attributes_for

そのため、ユーザーは電話を削除できます。もちろん、後でユーザーが電話なしで会社を編集しようとすると、エラーが発生します(The company must have at least one phone)。

会社(親)モデル:

class Company < ActiveRecord::Base
  PHONES_NUMBER_MIN = 1

  attr_accessible :name, :contact_details_attributes, ...

  has_many :contact_details, :as => :contactable, :dependent => :destroy

  validate do |company|
    check_phones_number
  end

  accepts_nested_attributes_for :contact_details, :allow_destroy => true, :reject_if => :all_blank

  private

  def phones_number_valid?
    kind = ContactDetail::Kind.phone
    phones = contact_details.select { |cd| cd.kind_id == kind.id }
    phones.size >= PHONES_NUMBER_MIN
  end

  def check_phones_number
    unless phones_number_valid?
      errors.add(:base, :phones_too_short, :count => PHONES_NUMBER_MIN)
    end
  end

  ...
end

ContactDetail(子)モデル:

class ContactDetail < ActiveRecord::Base
  attr_accessible :kind_id, :kind_value_source

  belongs_to :contactable, :polymorphic => true
  belongs_to :kind

  validates :kind_value_source, :presence => true, :length => {:maximum => 255}

  ...
end

注:元のバージョンを簡略化したので、目的は明確でした。これがコードの要点です。require_ifオプションを使用することにより、すべての電話の削除を禁止することができます。これはおそらく今のところ最良の選択肢です。でも、あなたの意見を聞きたいです。

私もこの質問を見つけて答えを適用しようとしましたが、あまり役に立ちませんでした。私が上で説明したのと同じ問題。私が見ているように、あなたがトレースを見ることができるようにフローチャートを描きました。 フローチャート

このような場合、どうすれば親モデルを検証できますか?

助けていただければ幸いです。

4

1 に答える 1

3

reject_if参照した質問から、を削除して の行を変更できますphones_number_valid?

phones = contact_details.select { |cd| cd.kind_id == kind.id && !cd.marked_for_destruction? }
于 2012-07-17T04:54:59.537 に答える