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: Peak Obsession 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