Dynamically adding validations to model instances

Hi,

I have code which generates a definition of a survey / questionnaire using a few related AR tables. The code I need help with is the code which converts the survey definition into an object I can pass to the view to generate the survey form for the user to fill in.

I have a non-AR object called SurveyData. It extends ValidatingBase, which is described here: http://wiki.rubyonrails.com/rails/pages/HowToUseValidationsWithoutExtendingActiveRecord
basically it lets you use ActiveRecord::Validations on a non-AR object.

What I want to do is dynamically read the questions that the survey needs to ask, and for each one, do the equivalent of:

class SurveyData
     attr_accessor fieldname
     validates_presence_of fieldname
end

I've tried all sorts of things. This is my current non-working version:

class SurveyData < ValidatingBase
   include Reloadable

   def add_required_fields(field_names)
     [field_names].flatten.each { |name|
       src=<<-END
         attr_accessor :#{name}
         validates_presence_of :#{name}
       END

       self.class.class_eval src, __FILE__, __LINE__
     }
   end
end

It appears to work, but my unit test fails because the validates_presence_of line actually adds a validation method to the base SurveyData class, which means a completely new instance of SurveyData gets constructed with a validation already present.

Any help would be most appreciated!

Jon

PS the unit test is:

require File.dirname(__FILE__) + '/../test_helper'

class SurveyDataTest < Test::Unit::TestCase

   def test_validateable
     sd = SurveyData.new
     assert_not_nil sd

     assert_raise(NoMethodError) {
       sd.foo
     }

     assert sd.valid?

     sd.add_required_fields 'foo'

     assert_respond_to sd, :foo
     assert_nothing_raised { sd.foo }

     assert_equal false, sd.valid?, "SurveyData shouldn't be valid (because we haven't set 'foo' yet)"

     sd.foo = "test"

     assert_equal sd.foo, "test"

     assert sd.valid?

     test_sd = SurveyData.new

     # **** THIS TEST FAILS:
     assert test_sd.valid?, "a different SurveyData should be valid (because we haven't yet added any validations to it)"

   end

end