How to Rippling validation effects from child to parent?

class Client < ActiveRecord::Base   validates_presence_of :cognome, :nome, :data_di_nascita,:badge   has_one :badge

end

When you validate the presence of an association refer directly to the column name:

validates_presence_of :cognome, :nome, :data_di_nascita,:badge_id

  def validate     errors.add(:client_id,"Badge già assegnato") if (self.client_id != nil) and (Badge.find(:all, :conditions => "client_id = #{self.client_id}").size > 1)   end

It looks like your validate method is trying to ensure the uniqueness of client_id if it's not nil. You can do that all with validates_uniqueness_of:

validates_uniqueness_of :client_id, :allow_nil => true

Aaron

Sorry about the mistake on the has_one :badge association. I forgot that the foreign key reference is on the belongs_to side.

I took another look at your models and what you want to accomplish and came up with this:

class Client < ActiveRecord::Base   has_one :badge

  # ensure client has a badge   def validate     errors.add_to_base('Client must have a badge!') if badge.nil?   end end

class Badge < ActiveRecord::Base   belongs_to :client   # ensure client has only one badge   validates_uniqueness_of :client_id, :allow_nil => true end

When validating that a Client has a Badge there is no attribute to associate the error with so use "add_to_base" to invalidate the entire object if the badge association is not present.

Aaron

I forgot to say that no two or more different clients can have the same badge associated. This is something I think has to be worked out defining a validate in the Client model, this way:

If I understand your database schema correctly its impossible for two clients to have the same badge. Your badges table has a "client_id" column, right? So a particular badge can only be associated with 1 client at a time, there's no need to validate something that can never happen.

Your other concern is preventing a client from having more than 1 badge. That's what this line in the Badge model takes care of: validates_uniqueness_of :client_id, :allow_nil => true

Now you may want to prevent a client from taking a badge that is already in use by another client. That's what it looks like your trying to do with this line: errors.add_to_base("badge already taken!") if Badge.count(:conditions => "client_id = #{self.id}") > 0

However, this line is checking that current client does not already have another badge assigned. Which is already addressed by the validates_uniqueness_of statement I mentioned above.

This is not exactly pretty, but it should work: def validate   if badge.nil?     # don't let the badge association be nil     errors.add_to_base("client must have a badge!")   else     # pull the old version of badge from the database     old_badge = Badge.find(badge.id)     # if the old badge already had a client_id set and its not for this client then add an error     errors.add_to_base("badge already taken!") if old_badge.client_id and old_badge.client_id != id   end end

Aaron