我有一个调查应用程序,基本上与Railscast 196一致,但有一个障碍:Railscast有一个Question
类,has_many :answers
,我有几个:
Question (self.abstract_class = true)
BasicQuestion < Question
MultipleChoiceQuestion < Question
为了完成这项工作,我不得不覆盖questions
Survey
中的Survey.rb
has_many :questions
accepts_nested_attributes_for :questions
def questions # simplified a bit for brevity
questions = []
[BasicQuestion, LikertQuestion, MultipleChoiceQuestion].each do |model|
questions += model.where(:survey_id => self.id)
end
questions
end
Survey_Controller.rb
def survey_params
params.require(:survey).permit(:name, :questions_attributes => [:id, :name])
end
getter,这看起来有点像kludge但不是太糟糕(有标准的方法吗?):
surveys/edit.html.erb
到目前为止,这么好。问题是:
再次来自Railscast,我在surveys/edit.html.erb
<%= f.fields_for :questions do |builder| %>
<%= render 'edit_question_fields', f: builder %>
<% end %>
:
{ "survey" => { "name" => "Howard", questions_attributes => { "id" => "1", "name" => "Vince" }}}
但是,这将返回以下形式的哈希:
ActiveRecord::StatementInvalid (Could not find table '')
Rails给我一个错误:Questions
-
大概是因为没有nested_attributes
表(它是一个抽象类)。
那么,我该如何解决呢?在不放弃Question
或完全继承的情况下,我可以想到四种方式:
_type
是抽象类),在params散列中包含Survey
字段,然后从那里开始。让Survey.rb
has_many :basic_questions
accepts_nested_attributes_for :basic_questions
has_many :multiple_choice_questions
accepts_nested_attributes_for :multiple_choice_questions
def questions
# same as before, still comes in handy
end
surveys/edit.html.erb
<% @survey.questions.each do |question| %>
<%= f.fields_for question do |builder| %>
<%= render 'edit_question_fields', f: builder %>
<% end %>
<% end %>`
分别处理每种问题类型:
{ "survey" => { "name" => "Howard", "basic_question" => { "id" => "1", "name" => "Vince" }, "multiple_choice_question" => { "id" => "1", "name" => "Naboo" }}}
这几乎可行,但现在我的哈希看起来像这样:
"basic_questions_attributes"
我需要索引的问题,例如"basic_question"
而不是questions_attributes=
- 有人知道怎么做吗?
覆盖Survey.rb中的QuestionsFormBuilder
以对其进行排序。
Question
对象来处理所有内容,与“Rails nested attributes form for polymorphic/single table inheritance associations”一致。显然,主要关注的是能够以最少的麻烦在以后放入新的Question
子类(或改变现有子类的行为)。
目前我倾向于使用选项#3,因为它看起来最简单,最优雅,但是,我不确定我是不是错过了一些更好的方法来做到这一点。 (或以某种方式搞砸了{{1}}子类化实现。)有没有人有更好的想法或更多类似Rails的方法来实现这一点?!
答案 0 :(得分:1)
看一下使用表单对象来封装逻辑和创建问题? http://railscasts.com/episodes/416-form-objects
我还会考虑使用STI,以便您的Survey.rb不需要重新定义问题