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?
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.
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
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.