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


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)

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 :client_id, :allow_nil => true


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?

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

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.


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

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 = #{}") > 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!")
    # pull the old version of badge from the database
    old_badge = Badge.find(
    # 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