2012-02-23 462 views
0

我在我的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 

我不知道如何驗證所有添加到一個人的項目屬於同一個域。我已經創建了一個驗證人員的方法,但是仍然可以在其他域中添加項目,保存在數據庫中的人員無效。

您是否看到這個問題的乾淨解決方案?

回答

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 

現在,到了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 

這爲我工作。這是你想要的嗎?

+0

事實上,它的工作原理 – Etienne 2012-02-23 17:53:35

0

,你可以設置爲個人定製的驗證方法(從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 
+0

我已經嘗試過這樣的解決方案,但是當更新一個新項目的項目時,數據庫被更新,而人員對象無效 – Etienne 2012-02-23 13:14:09