Подтвердить уникальность в ассоциации - PullRequest
11 голосов
/ 23 января 2012

Учитывая следующие классы:

class Candidate
  has_many :applications
  has_many :companies, :through => :job_offers
end

class JobOffer
  belongs_to :company
end

class Application
  belongs_to :candidate
  belongs_to :job_offer
end

enter image description here

Как я могу проверить предыдущее утверждение (в изображении) на Rails?

Добавление следующегопроверка корректности приложения не будет работать при обновлении:

def validate_uniqueness_of_candidate_within_company
  errors.add(:job_offer_id, "...") if candidate.companies.include?(company)
end

Причина, по которой при попытке изменить приложение на другой JobOffer той же компании кандидат.com.panies вернет эту компанию.

Я такжепопытался сделать что-то подобное в приложении:

validates_uniqueness_of :user_id, :scope => {:job_offer => :company_id}

Но это тоже не сработало.Любые идеи, чтобы решить эту проблему без использования 10 строк дерьмового кода?

Ответы [ 4 ]

14 голосов
/ 23 января 2012

Вероятно, существует много приемлемых подходов для решения вашей проблемы, но я думаю, суть в том, что вы пытаетесь применить ограничение уникальности для таблицы, которая (напрямую) не имеет всех атрибутов (оба company И user). Я бы нормализовал информацию company в таблице приложения (user_id, job_offer_id, company_id) и всегда устанавливал ее в обратном вызове before_save, чтобы соответствовать job_offer * company. Тогда вы сможете использовать проверку уникальности по области:

class JobApplication < ActiveRecord::Base
  belongs_to :user
  belongs_to :job_offer
  belongs_to :hiring_company, :class_name=>"Company", :foreign_key=>"company_id"

  before_save :set_hiring_company

  def set_hiring_company
   self.hiring_company = job_offer.hiring_company
  end

  validates_uniqueness_of :user_id, :scope => :company_id
end
0 голосов
/ 28 июня 2015

Для тех, кто нашел это сегодня. Ответ заключается в том, чтобы проверить, существуют ли уже существующие (предотвращает многократное использование), и пропустить, когда само приложение переключается.

def validate_uniqueness_of_candidate_within_company
  pre_existing = Application.includes(:candidate).includes(job_offer: :company).
    where(companies: { id: self.company.id }).
    where(candidates: { id: self.candidate.id })

  if pre_existing.present? && (!pre_existing.map(&:id).include? self.id)
    errors.add(:job_offer_id, "...")
  end
end
0 голосов
/ 23 января 2012

Как видно из изображения, у кандидата и предложения о работе будет много заявок, и кандидат может подать заявку только на одно предложение о работе на компанию. Таким образом, проверка уникальности кандидата, имеющего отношение к предложению о работе в заявке, может подойти.

class Candidate
  has_many :applications
  has_many :job_offers, :through => :applications
end

class JobOffer
  belongs_to :company
  has_many :applications
  has_many :candidates, :through => :applications
end

class Application
  belongs_to :candidate
  belongs_to :job_offer

  validates_uniqueness_of :candidate_id, :scope => :job_offer_id
end

Это предотвратит привязку приложения к одному и тому же кандидату на одно и то же предложение о работе. Кандидат может подать заявку на другие предложения о работе, верно?

И, как отмечает @ez., Лучше переименовать приложение во что-то более подходящее.

Надеюсь, это поможет.

0 голосов
/ 23 января 2012

Вот как я буду структурировать модели:

class Candidate
  has_many :applicatons
  has_many :job_offers
  has_many :offering_companies, :through => :job_offers
end

class Application
  belongs_to :candidate
end

class JobOffer
  belongs_to :candidate
  belongs_to :company

  validates_uniqueness_of :candidate_id, :scope => :company_id
end

class Company
end

Это должно работать! Btw. Я буду называть приложение чем-то другим, чтобы избежать путаницы с именами (у rails уже есть application.rb

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...