验证对象的关联

时间:2012-02-23 10:47:23

标签: ruby-on-rails ruby-on-rails-3 validation

我的rails开发中有一个奇怪的例子,我无法正常管理。 基本上,我有三个对象:域,项目和人;域名是一组人和项目。域可以有多个项目,项目可以有多个人,但项目只能在一个域中,人们只能在一个域中的项目中工作。

我把它表示如下:

class Domain < ActiveRecord::Base
    has_many :projects

class Project < ActiveRecord::Base
    belongs_to :domain
    has_and_belongs_to_many :persons

class Person < ActiveRecord::Base
    belongs_to :domain
    has_and_belongs_to_many :projects

我不知道如何验证添加到某人的所有项目都属于同一个域。我已经创建了一个验证人员的方法,但是仍然可以在其他域中添加项目,保存在数据库中的人员将无效。

您是否看到了解决此问题的干净解决方案?

2 个答案:

答案 0 :(得分:1)

所以,基本上,你想要验证一个人只从一个域获取项目。我想应该定义这个域,这意味着一个人应该有domain_id列。

您还有一个多对多关联,并且,由于关联需要一些验证,您还应该有一个连接模型(而不仅仅是没有模型的表)。我叫它Work。所以,我有这个:

class Domain < ActiveRecord::Base
  has_many :projects
end

class Project < ActiveRecord::Base
  belongs_to :domain

  has_many :works
  has_many :persons, :through => :works
end

class Work < ActiveRecord::Base
  belongs_to :project
  belongs_to :person
end

class Person < ActiveRecord::Base
  has_many :works
  has_many :projects, :through => :works
end

现在,您只需添加<{p>} Work模型

validate :projects_belong_to_apropriate_domains

def projects_belong_to_apropriate_domains
  if person.domain_id != project.domain.id
    errors[:base] << "A person may only take a project which belongs to his domain."
  end
end

这对我有用。这是你想要的吗?

答案 1 :(得分:0)

您可以为Person设置自定义验证方法(取自rails guides

validates :check_project_domain

def check_project_domain
  projects.all.each do |p|
    next if domains.exists?(p.domain.id)
    errors.add :project_domain "#{p} is not a member of allowed domains"
  end
end

我不确定您是否可以在某个关联上调用exists,如果没有,那么您可以用以下内容替换它:

domains.all.collect { |d| d.id }.include?(p.domain.id)

甚至:

domains.where(:id => p.domain.id).count > 0