好的,首先,我正在做一些非常复杂的事情。我可能走错了方向。
我目前拥有的是STI继承模型StateDescription。 StateDescription的子类描述了我可以关注的特定状态,例如“LocationHasItem”或“ItemNearOtherItem”或什么不是。
据我所知,我最终可能希望将其升级为多表继承模型,因为并非StateDescription的所有子类都使用所有可能的变量(尽管存在高度重叠)。
这些StateDescriptions由另一个类以“has_many / belongs_to”关系拥有。
所以,在其他课程的表格中,我有:
<%= f.fields_for :conditions do |e| %>
<br>
<%= render :partial =>"/state_descriptions/form", :locals => {:e => e, :universe => @story_section.universe, :div_id => "condition"}%>
<Br>
<% end %>
StateDescription本身检查它应该呈现的类型,然后像这样渲染适当的部分(为了清楚起见,只显示一个子类):
<div id="<%=div_id%><%=e.object.id%>">
<li>
<%= e.select(:type, StateDescription.subclasses.collect{|x| x.to_s}) %>
<br>
<%= e.label "Inverted?" %>
<%= e.check_box :invert %>
<Br>
<% if e.object.type.to_s == "StateDescription::ItNear" %>
<%= render :partial =>"/state_description/it_nears/form", :locals => {:e => e, :universe => universe, :div_id => div_id}%>
<% end %>
<% end %>
</li>
</div>
子类部分看起来像:
<%=e.collection_select 'item_id', universe.items, :id, :title%>
<%= e.object.title_middle_fragment%>
<%=e.collection_select 'item2_id',universe.items, :id, :title%>
因此,表格对所有子类开始相同,并且只在需要时才有所不同。
这非常有效,我对它非常满意......直到我决定在从选择输入字段中选择子类时,我想让ajax更新具有正确格式的网页。
然后我意识到我无法将表单助手引用(在本例中为“e”)传递给控制器的部分。
对于这种情况是否有最好的做法,或者我只是在做一些如此复杂的事情我应该直接使用jQuery或其他东西并将其留下来?
如果我在每个子类形式中放入整个表单(包括每个子类共有的东西),那似乎不是很干。不仅如此,我不确定我是否能够将StateDescription子类重新关联到父类......
但是,如果我这样做AJAX,我想我可以不担心嵌套表单,只是让父项成为隐藏字段或其他东西,并让StateDescriptions通过AJAX自行保存?
这是最好的解决方案(如果它可以工作吗?)还是有一些我想念的简单Rails方式?
答案 0 :(得分:0)
好吧,我仍然不知道这是否是最简单或干燥的方式,但我最终将整个表单放在部分中,然后就不用打扰嵌套表单了。这适用于AJAX解决方案。
这让我伤心重复他们的共同点每次有表单元素,但它是值得的AJAX功能。
我会尝试多做一些DRY,它发生在我身上我可以尝试使子类部分不需要表单,但它仍然可以调用一个超类形式部分插入每个子类共有的元素。 / p>
答案 1 :(得分:0)
我遇到了与STI模型类似的问题,该模型由“has_many / belongs_to”关系中的另一个类所拥有。为了动态地为其他类构建表单,我使用cocoon
gem和simple_form
。
Cocoon添加了为每个具体类动态添加/删除字段的方法,这些方法继承自基础STI类。
例如(Publication是所有者类,Item是基本STI模型,Post,Video和Image继承自它):
# _form.html.haml
= simple_form_for @publication, :html => { :multipart => true } do |f|
= f.simple_fields_for :items do |item|
= render 'item_fields', :f => item
= link_to_add_association 'Add a Post', f, :items, :wrap_object => Proc.new { |item| item = Item.new }
= link_to_add_association 'Add an Image', f, :items, :wrap_object => Proc.new { |item| item = Image.new }
= link_to_add_association 'Add a Video', f, :items, :wrap_object => Proc.new { |item| item = Video.new }
= f.button :submit, :disable_with => 'Please wait ...', :class => "btn btn-primary", :value => 'Save'
:wrap_object
proc将具体类传递给item_fields
,它会呈现正确的部分,例如image_fields
或video_fields
或其他。
我希望这会有所帮助。
为这个问题写了一个更长的解释