Rails:嵌套表单,带有STI继承通知表单,如何使用AJAX?

时间:2013-09-06 15:39:02

标签: ruby-on-rails ajax

好的,首先,我正在做一些非常复杂的事情。我可能走错了方向。

我目前拥有的是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方式?

2 个答案:

答案 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_fieldsvideo_fields或其他。

我希望这会有所帮助。

我在http://www.powpark.com/blog/programming/2014/05/07/rails_nested_forms_for_single_table_inheritance_associations

为这个问题写了一个更长的解释