In my Rails application, I am implementing a survey-like form which allows users to fill out answers to a dynamically changeable set of questions. Currently, I'm planning to support three different "types" of questions: Yes/No, Rating (on a 1-5 scale), and Text. For each of these question types, I need slightly different behavior for the corresponding Answer model (to accommodate different methods, validation requirements, etc). I am currently trying to implement these different behaviors using single table inheritance, like so:
class Question < ActiveRecord::Base
validates_presence_of :question_type
# ...
end
class Answer < ActiveRecord::Base
belongs_to :question
validates_presence_of :answer
# ...
end
class YesNoAnswer < Answer
validates :answer, inclusion: {in: %w(Yes No N/A)}
# ...
end
class RatingAnswer < Answer
validates :answer, numericality: { only_integer: true }, inclusion: {in: 1..5}
def answer
self[:answer].to_i
end
# ...
end
class TextAnswer < Answer
validates :answer, length: { minimum: 2 }
# ...
end
The problem is that with single-table inheritance the chosen class is normally determined by a field in the database for each record. (By default, this field is "type"
, but you can change this by setting inheritance_column
).
In my case though, the type of the answer should always match the type of its corresponding question, making the need to manage an extra database field like this awkward and redundant. So rather than rely strictly on what's in the database, I want to determine programmatically what class should be used for a given record. E.g.:
class Answer < ActiveRecord::Base
# I want a value on the associated question to determine this record's type.
# Simply defining a type method as shown here doesn't work though.
def type
question.try(:question_type)
end
end
Is this possible? If so, how?