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
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