Validates presence of special conditions not working

Here is the validation being used which is not working..

validates_presence_of :name => :controller_name, :if => :redirect?,
:message => "must have the same name as the controller."

The model has a string field for name.
The model has a boolean field for redirect.
The model has a string field for controller_name.

What I want to do is ensure that if the redirect box is checked for
true, that the name field matches the controller_name field precisely.

I'm not sure if validates_presence_of will do it. I may have to create
a custom validation but am unsure how to proceed.

Much appreciation in advance...

Thanks.

validates_presence_of doesn't do that.

Custom validations aren't scary. Adding a class method like

def validates_foo(*attr_names)
  options = attr_names.extract_options!
  validates_each(attr_names, options) do |record, attr_name, value|
    record.errors.add(attr_name, options[:message]) if ...
    end
  end
end

lets you do

validates_foo :attr1, :attr2

You get stuff like :if and :unless for free

Fred

Thanks for the explanation Fred.

I tried doing this but it's not working properly:

def self.validates_is_exact(*attr_names)
  options = attr_names.extract_options!
  validates_each(*(attr_names << options)) do |record, attr_name, value|
    if record.send( options[:compare_field] ) == value
      record.errors.add(attr_name, options[:message])
    end
  end
  true
end

validates_is_exact :name, :compare_field => :controller_name, :if =>
:redirect?, :message => "must have the same name as the controller."

And ran a test in the console:

e = Page.new
e.name = "testname"
e.redirect = true
e.controller_name = "testname"
e.valid?

e.valid?

=> false

Any idea what I might be doing wrong here?

I was reading the errors wrong. It's working properly.

Thanks Fred for the advice.

Here is the finished validation, corrected:

def self.validates_is_exact(*attr_names)
  options = attr_names.extract_options!
  validates_each(*(attr_names << options)) do |record, attr_name, value|
    if record.send( options[:compare_field] ) != value
      record.errors.add(attr_name, options[:message])
    end
  end
  true
end

validates_is_exact :name, :compare_field => :controller_name, :if =>
:redirect?, :message => "must have the same name as the controller."

Basically, it compares the :name field value with the :compare_field
field.value and if they are the same, validation is successful. If they
are different, it throws my custom message.

Thanks again Fred. It was much easier than I anticipated.