# Has\_many and validates\_associated

**URL:** <https://www.ruby-forum.com/t/has-many-and-validates-associated/131027>\
**Category:** Rails\
**Created:** [March 5, 2008, 10:42am UTC](https://www.ruby-forum.com/t/has-many-and-validates-associated/131027 "2008-03-05T10:42:47Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![grey-lantern](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/90ced4/32.png) [@grey-lantern](https://www.ruby-forum.com/u/grey-lantern)\
**Post date:** [March 5, 2008, 10:42am UTC](https://www.ruby-forum.com/t/has-many-and-validates-associated/131027/1 "2008-03-05T10:42:47Z")

</div>

Given the following code:

class MyClass \< ActiveRecord::Base

has\_many :technical\_contacts  
has\_many :schedule\_contacts

validates\_associated :technical\_contacts, :schedule\_contacts

protected

def validate  
validate\_contacts(technical\_contacts)  
validate\_contacts(schedule\_contacts)  
end

private

def validate\_contacts(contacts)  
contacts.each\_with\_index{|contact, i|  
(i+1).upto(contacts.length-1) do |j|  
if contacts[j].email == contact.email  
contacts[j].errors.add(:email,  
‘You have already provided this email  
address’)  
end  
end  
}  
end

end

If my validate\_contacts method adds errors to some contact objects, I  
would expect @myclass.save to fail but it does not. I have tested that  
the objects are invalid using the “valid?” method and they are so I  
don’t understand what is going wrong. Can anyone please help?

---

<div class="post-metadata">

**Author:** ![grey-lantern](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/90ced4/32.png) [@grey-lantern](https://www.ruby-forum.com/u/grey-lantern)\
**Post date:** [March 6, 2008, 12:12pm UTC](https://www.ruby-forum.com/t/has-many-and-validates-associated/131027/2 "2008-03-06T12:12:19Z")

</div>

Craig N. wrote:

> ```
> if contacts[j].email == contact.email
> 
> ```
> 
> If my validate\_contacts method adds errors to some contact objects, I  
> would expect @myclass.save to fail but it does not. I have tested that  
> the objects are invalid using the “valid?” method and they are so I  
> don’t understand what is going wrong. Can anyone please help?

Custom “validate” methods run after all other validations, so  
validates\_associated will run before the contact errors are added.

You can either get rid of the validates\_associated call and add  
the base errors in the validate\_contacts method, or move the  
validate\_contacts calls to a :validates\_each call that is  
placed before the validates\_associated call.

–  
We develop, watch us RoR, in numbers too big to ignore.

---

<div class="post-metadata">

**Author:** ![grey-lantern](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/90ced4/32.png) [@grey-lantern](https://www.ruby-forum.com/u/grey-lantern)\
**Post date:** [March 7, 2008, 10:09am UTC](https://www.ruby-forum.com/t/has-many-and-validates-associated/131027/3 "2008-03-07T10:09:14Z")

</div>

> Mark Reginald J. wrote:  
> You can either get rid of the validates\_associated call and add  
> the base errors in the validate\_contacts method, or move the  
> validate\_contacts calls to a :validates\_each call that is  
> placed before the validates\_associated call.\>

Hi Mark,

I tried your suggestion but the save method is still working when it  
shouldn’t. Here is my code:

class MyClass \< ActiveRecord::Base

has\_many :technical\_contacts  
has\_many :schedule\_contacts

validates\_each :technical\_contacts do |model, attr, value|  
value.each\_with\_index{|contact, i|  
(i+1).upto(value.length-1) do |j|  
if value[j].email == contact.email  
value[j].errors.add(:email,  
‘You have already provided this email  
address’)  
end  
end  
}  
end

validates\_associated :technical\_contacts, :schedule\_contacts

end

Any help would be most appreciated.

Thanks,

Craig

---

<div class="post-metadata">

**Author:** ![grey-lantern](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/90ced4/32.png) [@grey-lantern](https://www.ruby-forum.com/u/grey-lantern)\
**Post date:** [March 7, 2008, 8:59pm UTC](https://www.ruby-forum.com/t/has-many-and-validates-associated/131027/4 "2008-03-07T20:59:16Z")

</div>

Craig N. wrote:

> ```
> (i+1).upto(value.length-1) do |j|
> 
> ```
> 
> end

With what you have the error messages you add to a contact in the  
validates\_each will be cleared before valid? is called on each  
of them during the validates\_associated.

Is something like this possible?

class Contact \< ActiveRecord::Base  
validates\_uniqueness\_of :email, :scope =\> :my\_class\_id,  
:message =\> ‘^You have already provided this email address’  
end

class TechnicalContact \< Contact end  
class ScheduleContact \< Contact end

class MyClass \< ActiveRecord::Base  
has\_many :technical\_contacts  
has\_many :schedule\_contacts  
validates\_associated :technical\_contacts, :schedule\_contacts  
end

Otherwise, drop the validates\_associated:

validates\_each :technical\_contacts, :schedule\_contacts do |m, a, v|  
v.each\_with\_index{ |contact, i|  
(i+1).upto(v.length-1) do |j|  
if value[j].email == contact.email  
value[j].errors.add(:email, ‘Email already provided’)  
m.errors.add\_to\_base(a, ‘Bad contact email address’)  
end  
end  
}  
end

–  
We develop, watch us RoR, in numbers too big to ignore.
