我有一个名为Pair的模型,其中has_many:问题,每个问题has_one:answer。
我一直在关注这个railscast on creating nested forms,但是当我点击“添加问题”链接时,我想生成一个问题字段和它的答案字段。
跟随railscast后,这就是我所拥有的:
.. Javascript角/ common.js.coffee:
window.remove_fields = (link)->
$(link).closest(".question_remove").remove()
window.add_fields = (link, association, content)->
new_id = new Date().getTime()
regexp = new RegExp("new_" + association, "g")
$(link).before(content.replace(regexp, new_id))
application_helper.rb:
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.simple_fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "window.add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")", class: "btn btn-inverse")
end
视图/对/ _form.html.erb:
<%= simple_form_for(@pair) do |f| %>
<div class="row">
<div class="well span4">
<%= f.input :sys_heading, label: "System Heading", placeholder: "required", input_html: { class: "span4" } %>
<%= f.input :heading, label: "User Heading", input_html: { class: "span4" } %>
<%= f.input :instructions, as: :text, input_html: { class: "span4 input_text" } %>
</div>
</div>
<%= f.simple_fields_for :questions do |builder| %>
<%= render 'question_fields', f: builder %>
<% end %>
<%= link_to_add_fields "<i class='icon-plus icon-white'></i> Add Another Question".html_safe, f, :questions %>
<%= f.button :submit, "Save Pair", class: "btn btn-success" %>
<% end %>
_question_fields.html.erb partial:
<div class="question_remove">
<div class="row">
<div class="well span4">
<%= f.input :text, label: "Question", input_html: { class: "span4" }, placeholder: "your question...?" %>
<%= f.simple_fields_for :answer do |builder| %>
<%= render 'answer_fields', f: builder %>
<% end %>
</div>
</div>
</div>
_answer_fields.html.erb partial:
<%= f.input :text, label: "Answer", input_html: { class: "span4" }, placeholder: "your answer" %>
<%= link_to_function "remove", "remove_fields(this)", class: "float-right" %>
我对reflect_on_association部分特别感到困惑,例如调用.new
如何创建关联?我通常需要使用.build
对于has_one,我使用.build_answer
而不是answers.build
- 那么这对jQuery部分意味着什么呢?
答案 0 :(得分:1)
检查这个的一种方法是在Rails控制台中运行帮助程序脚本。
new_object = f.object.class.reflect_on_association(association).klass.new
您正在获取Form对象并找到它所用的类(f.object.class - 在本例中为 pair ),然后使用reflect_on_association(association) - 返回AssociationReflection对象命名关联(从参数传递为符号,即:问题)。
您可以使用reflect_on_all_associations查看每个类的所有这些AssociationReflection对象。
在此之后,您需要AssociationReflection所代表的类(这就是您使用klass而不是类的原因) - 然后您创建该类的新实例。
为什么你不使用build _#{association_name}或#{association_name} .builds,而不是new,可能是因为脚本不知道该组件是has_one还是HABTM,直到它已经检索到一个实例为止相关对象和附加逻辑是不值得的。
http://api.rubyonrails.org/classes/ActiveRecord/Reflection/ClassMethods.html
顺便说一下,修改后的铁路广播使用了一种稍微不同的生成关联对象的方式:但是这个想法是相同的(在这种情况下,您发送 - 调用 - 表单对象上的方法,然后生成相关的类)
new_object = f.object.send(association).klass.new
至于在帮助器中使用两个模型吗?
application_helper.rb
def link_to_add_nested_fields(name, f, association, nested_association)
new_object = f.object.class.reflect_on_association(association).klass.new
new_object.send(nested_association).new
fields = f.simple_fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "window.add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")", class: "btn btn-inverse")
end
E.g
<%= link_to_add_fields "<i class='icon-plus icon-white'></i> Add Another Question".html_safe, f, :questions, :answer %>
答案 1 :(得分:0)
下面的作品。我没有使用 form_for 代替 simple_form_for ,而没有使用 fields_for 代替 simple_fields_for 。多亏了粘贴
def link_to_add_nested_fields(名称,f,关联,嵌套关联)
new_object = f.object.class.reflect_on_association(association).klass.new
id = new_object.object_id#需要索引,这一点很重要。在浏览器中检查
nested_new_object = new_object.class.reflect_on_association(nested_association).klass.new
fields = f.fields_for(关联,new_object,:child_index => id)做| builder |
builder.fields_for(nested_association, nested_new_object, :child_index => id) do |builder1|
render(association.to_s.singularize + "_fields", association.to_s.singularize.to_sym => builder) + render(nested_association.to_s.singularize + "_fields", nested_association.to_s.singularize.to_sym => builder1)
end
结束
link_to(name,'javascript:void(0)',类:“ add_fields”,数据:{id:id,fields:fields.gsub(“ \ n”,“”)})
结束