Reputation: 63
I have a weird case in my rails development that I'm not able to manage properly. Basically, I have three objects: Domain, Project and Person ; a domain is a group of persons and projects. Domains can have several projects and projects can have several people however a project can only be in one domain and people can only work for projects in one domain.
I have represented it as following:
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
I don't know how to validate that all the projects added to a person belongs to the same domain. I have created a method for validating persons however it is still possible to add projects in other domains, the person saved in database will just not be valid.
Do you see a clean solution to this problem?
Upvotes: 0
Views: 173
Reputation: 9335
So, basically, you want to validate that a person takes projects only from one domain. I suppose this domain should be defined, meaning a person should have a domain_id
column.
You also have a many-to-many association, and, since the association needs some validations, you should have also a join model (instead of just a table without a model). I called it Work
. So, I have this:
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
Now, to the Work
model you just add
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
This worked for me. Is this what you wanted?
Upvotes: 1
Reputation: 7196
You could setup a custom validation method for Person (taken from the 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
I'm not to sure if you can call exists
on a association, if not then you could replace it with something like:
domains.all.collect { |d| d.id }.include?(p.domain.id)
or even:
domains.where(:id => p.domain.id).count > 0
Upvotes: 0