基于 hash 的存储,方便是方便,但总感觉这种方式的存储,没有固定 field 形式的存储性能好。维护也困难很多。 如果有我两个 survey,我希望针对这两个 survey,分别有不同的存储文档:
# survey 1: (named with survey.id.to_s)
:field name, :type => string
:field email, :type => string
:field question1.id, :type => integer
:field question2.id, :type => bollean
# survey 2: (named with survey.id.to_s)
:field score :type => integer
:field question1.id :type => string
这样的话,如何才能实现?
呼唤 @xdite女神!
有点混淆类和文档,明白只需文档即可。但关键是如何才能动态的创建文档呢,另外,针对不同 survey,每个文档具有不同的 field,不同的 field,类别和一些 validation 也不同。
问卷格式已经没问题,主要是问卷结果。原来 thundersurvey 实现是通过创建 survey.id.to_s 为名称的类。觉得这种方式值得选择。 如果拆解成不同类别问题用不同 model,倒是相对容易实现。
具体效果可参考:http://www.hujoy.com/surveys/ ,任何一个 survey 预览,可以发现现在这段代码,无法创建相应的存放调查结果的 response 实例。
@Rei 这段代码如何?是从 thundersurvey 上复制来的一段,但原来是基于 MongoMapper 的,移植到 Mongoid 一直移植不成功。
def user_klass
klass ||= Class.new
klass.send(:include, Mongoid::Document)
klass.send(:include, Mongoid::Timestamps)
klass.collection_name = self._id.to_s
klass.key "created_at", DateTime
klass.class_eval <<-METHOD
def id
self._id.to_s
end
def persisted?
!new_record?
end
METHOD
klass.instance_eval <<-NAME
def name
'Response'
end
NAME
self.questions.each do |question|
klass.key "q#{question.id}", String
klass.validates_presence_of "q#{question.id}".to_sym, :message => I18n.t('activemodel.errors.messages.blank') if question.required_question
klass.validates_uniqueness_of "q#{question.id}".to_sym, :message => I18n.t('activemodel.errors.messages.taken') if question.unique
if question.input == 'check' || question.input == 'radio'
klass.class_eval <<-METHOD
alias_method :old_q#{question.id}=, :q#{question.id}=
def q#{question.id}=(choices)
if !choices.is_a?(Array)
self.old_q#{question.id}= choices
return
end
if choices.include?('_other')
choices.delete('_other')
other_options = choices.detect {|c| c.is_a?(Hash)}
choices << other_options['other']
end
choices.reject! {|c| c.is_a?(Hash) || c.blank?}
self.old_q#{question.id}= choices.join("\n")
end
METHOD
end
end
klass
end
@Rei 能不能详细点呢?哪怕再多三五行代码示例。
明天见机行事,行外人士第一次参加这类活动。
有没有比较好的方案?