# Cross Model Validation

**URL:** <https://www.ruby-forum.com/t/cross-model-validation/176213>\
**Category:** Rails\
**Created:** [September 26, 2009, 8:02pm UTC](https://www.ruby-forum.com/t/cross-model-validation/176213 "2009-09-26T20:02:31Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![nbnbnb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/a87d85/32.png) [@nbnbnb](https://www.ruby-forum.com/u/nbnbnb)\
**Post date:** [September 26, 2009, 8:02pm UTC](https://www.ruby-forum.com/t/cross-model-validation/176213/1 "2009-09-26T20:02:31Z")

</div>

So I have this question:

Suppose I have these 3 models:

class Company \< ActiveRecord::Base  
has\_many :departments  
has\_many :employees  
end

class Department \< ActiveRecord::Base  
has\_many :employees  
belongs\_to :company  
end

class Employee \< ActiveRecord::Base  
belongs\_to :company  
belongs\_to :department  
end

Furthermore, suppose the domain I am modeling requires that I support  
the existence of employees that do not belong to any department  
(otherwise I would declare that Company has\_many :employees, :through  
=\> :departments instead).

As I am working with the Department model, I am thinking that it is  
conceivable that a mistake can be made in the code to allow an  
employee from a company to be incorrectly assigned to a department in  
another company. Hence, it might be a good idea to write some custom  
validation to ensure an employee and a department belong to the same  
company before they associated together.

Since associate a department and an employee together in one of two  
ways, I would need validation logic in both models. So I am thinking  
it would involve something like:

1. In the Department model

def validate  
self.errors.add(:employees, “must all belong to same company”) if  
self.employees.collect { |e| e.company\_id }.uniq.length \> 1  
end

2 In the Employee model:

def validate  
self.errors.add(:department, “must belong to the same company”) if  
self.department && self.department != self.company  
end

However, having to write two separate methods to support a single  
business rule feels not so DRY or elegant. Is there a better way to  
go?

Thanks!

---

<div class="post-metadata">

**Author:** ![nbnbnb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/a87d85/32.png) [@nbnbnb](https://www.ruby-forum.com/u/nbnbnb)\
**Post date:** [September 27, 2009, 3:55pm UTC](https://www.ruby-forum.com/t/cross-model-validation/176213/2 "2009-09-27T15:55:19Z")

</div>

On Sat, Sep 26, 2009 at 2:01 PM, nb [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> class Department \< ActiveRecord::Base  
> the existence of employees that do not belong to any department  
> (otherwise I would declare that Company has\_many :employees, :through  
> =\> :departments instead).

Well one way to finesse this might be to have a fictional/notional  
catch-all department for each company, like “company staff” which acts  
as a placeholder for employes not actually belonging to a ‘real’  
department.

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)
