我有一个调查应用程序,基本上是沿着 Railscast 196 的路线,但有一个障碍:Railscast 有一个 Question
类,其中 has_many :answers
, 我有一些:
Question (self.abstract_class = true)
BasicQuestion < Question
MultipleChoiceQuestion < Question
为了完成这项工作,我必须覆盖
questions
setter/getter 在 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
到现在为止还挺好。问题是这样的:
再次来自 Railscast,我在
surveys/edit.html.erb
中有这个: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" }}}
Rails 给我一个错误:
ActiveRecord::StatementInvalid (Could not find table '')
——大概是因为没有
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
对象来处理一切,沿着“Rails nested attributes form for polymorphic/single table inheritance associations”的路线。 显然,一个主要问题是能够放入新的
Question
稍后以最少的麻烦创建子类(或更改现有子类的行为)。目前我倾向于使用选项 #3,因为它看起来最简单和最优雅,但是,我不确定我是否错过了一些更好的方法来做到这一点。 (或者以某种方式搞砸了
Question
子类化实现。)有没有人有更好的想法或更像 Rails 的方法来让它工作?!
最佳答案
看看用一个表单对象来封装问题的逻辑和创建? http://railscasts.com/episodes/416-form-objects
我还会考虑使用 STI,以便您的 Survey.rb 不需要重新定义问题
关于ruby-on-rails - 如何使用继承和嵌套属性构建 Rails 表单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20035694/