Question

Can't find a best way of getting this done easily I want to come up with database model for the following problem.

There is a Deal table which has one associated account table. Each account can have many contacts. Now one deal need to assign a primary contact which must be one among the many contacts of the associated account. How to make sure that the primary contact is one of the account contacts.

Deal Table
  account_id
  primary_contact_id

Account Table
  name and other params

Contact Table
  account_id
  phone, email etc.

Eg. class which I use currently

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

I can add validation in deal model or controller to make sure that contact getting added is one among its account contacts. But how to take care of following cases:

  1. Deleting a contact from an account should make sure that corresponding contact_id of the deal table is set to nil
  2. Deleting an account associated with a deal should make sure that contact_id of that deal table is nullified
  3. Updating an account association should make sure that contact_id of the deal is nullified.
Was it helpful?

Solution

May be you could use model callbacks, e.g.:

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

OTHER TIPS

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top