如何向rails模型添加验证,这取决于另一个模型

时间:2013-11-26 16:55:47

标签: mysql ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2 ruby-on-rails-3.1

找不到轻松完成此操作的最佳方法 我想针对以下问题提出数据库模型。

有一个Deal表,其中有一个关联的帐户表。每个帐户都可以有多个联系人。现在,一笔交易需要分配一个主要联系人,该主要联系人必须是相关帐户的多个联系人中的一个。如何确保主要联系人是其中一个帐户联系人。

Deal Table
  account_id
  primary_contact_id

Account Table
  name and other params

Contact Table
  account_id
  phone, email etc.

EG。我目前使用的课程

class Deal < ActiveRecord::Base
  belongs_to :account
  belongs_to :contact
end

class Account < ActiveRecord::Base
  has_many :contacts
  has_many :deals
end

class Contact < ActiveRecord::Base
  belongs_to :account
  has_many :deals
end

我可以在交易模型或控制器中添加验证,以确保添加的联系人是其帐户联系人之一。但如何照顾以下情况:

  1. 从帐户中删除联系人应确保将交易表的相应contact_id设置为nil
  2. 删除与交易相关联的帐户应确保该交易表的contact_id无效
  3. 更新帐户关联应确保交易的contact_id无效。

2 个答案:

答案 0 :(得分:0)

class Deal

  validate :contact_is_among_the_contacts_in_associated_account

  private

  def contact_is_among_the_contacts_in_associated_account
    errors.add(:contact_id, "Your error message") unless contact.in?(account.contacts)
  end

end

答案 1 :(得分:0)

可能你可以使用模型回调,例如:

class Deal < ActiveRecord::Base
  belongs_to :account
  belongs_to :contact

  before_update :nullify_contact_association, :if => lambda{|i| i.account_id_changed?}

  private
  # Nullify contact_id of the deal if it's account association was changed
  def nullify_contact_association
    self.contact_id = nil
  end
end

class Account < ActiveRecord::Base
  has_many :contacts
  has_many :deals

  before_destroy :nullify_dependencies

  private

  #Deleting an account associated with a deal should
  #make sure that contact_id of that deal table is nullified
  def nullify_dependencies
    self.deals.update_all(:contact_id => nil) if deal.present?
  end
end

class Contact < ActiveRecord::Base
  belongs_to :account
  has_many :deals

  before_destroy :nullify_dependencies

  private

  #Deleting a contact from an account should make sure
  #that corresponding contact_id of the deal table is set to nil
  def nullify_dependencies
    self.deals.update_all(:contact_id => nil) if account.present?
  end
end