【问题标题】:Anyone know how to save many objects in one form?任何人都知道如何以一种形式保存许多对象?
【发布时间】:2010-10-19 14:17:36
【问题描述】:

我正在尝试将表单中的许多对象保存到一个预先存在的父对象。

- form_for :parent_object do |f|

这是我表格的开始。然后在其中,我会这样做:

  - 2.times do
    - fields_for :child_object do |f|

现在,如果我要保存它,它将呈现为 ParentObject_Controller 更新操作,该操作将失败,因为更新无法识别新对象。

因此,如果我想呈现适当的保存操作,我必须这样设置:

- form_for [@parent_object, @child_object] do |f|
  - 2.times do
    - fields_for :child_object do |f|

然后此表单呈现保存操作,但保存最后一个 child_object。

我会向您展示我的控制器,但几乎没有意义,因为它非常错误。

我的问题是,如何将表单中的许多对象保存到一个预先存在的父对象?

我广泛研究了 Ryan Bate 的作品,以及许多其他博客和关于此的 SO 帖子。似乎没有什么真正指向专门为一个预先存在的父对象创建新的子对象。

更新:

我的印象是我必须为 def update 切换 parent_object 的控制器操作。

  elsif params[:parent_object][:child_object]
    @child_object = Child_Object.new(params[:child_object])
    if @child_object.valid? && @parent_object.referrals << @child_object
      redirect_to new_parent_object_child_object_path(@parent_object)
    else
      render :action => :new
    end

在调试器中,如果我将调试器放在def update 的根目录下,然后写:

>> params[:parent_object]
#=> nil

有趣!这意味着当 child_object 发送到 parent_object 控制器时,不会为其填写参数。哈哈,虽然不知道怎么办..

不幸的是,该代码不起作用,这只是我试图接近。 ;)

【问题讨论】:

    标签: ruby-on-rails forms model nested-forms


    【解决方案1】:

    好的,让我们再试一次。取自 RB's screencast 的代码,替换了对象名称:

    <% form_for @parent_object do |f| %>  
      <%= f.error_messages %>  
      <!-- some field of parent object here -->
      <p>  
        <%= f.label :name %><br />  
        <%= f.text_field :name %>  
      </p>  
      <% f.fields_for :child_objects do |builder| %>  
      <!-- some fields for child objects -->
      <p>  
        <%= builder.label :content, "Some content for child object" %><br />  
        <%= builder.text_area :content, :rows => 3 %>  
        <%= builder.check_box :_destroy %>  
        <%= builder.label :_destroy, "Remove child object" %>  
      </p>  
      <% end %>  
      <p><%= f.submit "Submit" %></p>  
    <% end %>
    

    这是@parent_object 的表单,其中包含:child_objects 的字段。当然,您必须用自己的字段替换字段。

    要完成这项工作,您必须在构造函数中构建子对象:

    def new  
      @parent_object = ParentObject.new  
      3.times { @parent_object.child_objects.build }  
    end 
    

    类似地在edit 方法中,你会这样做:

    def edit  
      @parent_object = ParentObject.find(params[:id])
      3.times { @parent_object.child_objects.build }  
    end
    

    要使其工作,您需要为子对象定义嵌套属性:

    class ParentObject < ActiveRecord::Base  
      has_many :child_objects, :dependent => :destroy  
      accepts_nested_attributes_for :child_objects
    end    
    

    希望这会有所帮助 - 这正是 RB 在他的截屏视频中提出的。如果您需要进一步解释,请在 cmets 中告诉我。

    -- 编辑--

    parent_object_controller.rb中的更新方法只是一个标准的:

    def update
      @parent_object = ParentObject.find(params[:id])
      if @parent_object.update_attributes(params[:parent_object])
        flash[:notice] = "Successfully updated parent object."
        redirect_to @parent_object
      else
        render :action => 'edit'
      end
    end
    

    但是感谢 ParentObject 中的accepts_nested_attributes_for,嵌套实例也将被创建。

    我没有在此回复中包含所有模型和控制器代码。您可以通过从 github 下载 source code for this episode 来查看其余代码。

    【讨论】:

    • 哇,我感激不尽。真的,这个特定的截屏视频可能是最接近的,我同意。所以..我在这里遇到的大难题是,当我单击提交或保存时,呈现的操作正在寻找 parent_object 的更新操作.. 啊.. 越来越近了。我想我只需要用父母的控制器更新一些东西?
    • 日志:Processing Parent_ObjectsController#update (for ::1 at 2010-10-19 12:10:43) [PUT] Parameters: {"commit"=&gt;"Submit", "Child_Objects"=&gt;{"name"=&gt;"jhkhjk", "org_name"=&gt;"jhkjhk", "town"=&gt;"kjhkjh", "email"=&gt;"jhkjh"}, "action"=&gt;"update", "_method"=&gt;"put", "authenticity_token"=&gt;"F2ZA2/BilvDrcOv+4XZ8Md63mbZBce/y9hIjJJZ42pw=", "id"=&gt;"1", "controller"=&gt;"Parent_Objects"}
    • 啊,感谢您的跟进。是的,我有。麻烦的是它无法识别params[:parent_object],无论出于何种原因。非常奇怪,因为我有很多 child_objects 以完全相同的方式工作,而且它们都没有识别 parent_object 的麻烦。
    • 您的日志显示没有发送 parent_object 的数据,只有 child_objects。不知道为什么会这样。仔细将您的表单与我作为示例给出的视图代码 (form_for) 进行比较。尝试下载并运行 RB 的示例并将您的代码和日志输出与它进行比较。
    【解决方案2】:

    你可以看看this answer我给了一个类似的问题。有两种选择:使用单独的表单,或使用单个表单。

    您只需将moderate_names_path 更改为您的父模型实例的正确路径(当然还有您要修改的字段集)。您可以使用polymorphic_path

    polymorphic_path([@parent_object, @child_object])
    

    【讨论】:

    • 我已经为此设置了明确的网址。 - form_for [@parent_object, @child_object :url =&gt; parent_object_child_object_path do |f| 为什么要做多态路径?您是说允许以一种形式保存多个对象?
    • 嗯.. 如果我要为 parent_object 创建一个自定义 def,那会包括什么?感谢您的帮助,我已经坚持了好几天了。 :D
    • 好吧,也许这些例子并不是你所需要的。您尝试过哪些 RB 截屏视频?这个:Nested Model Form?它似乎准确地描述了您想要的内容。
    • 我已经看了 10 倍以上,包括复杂形式 1-3。嵌套模型表单不起作用,因为它引用了 pre-existing child_objects,而我的是 new 对象。
    • 查看我的其他答案 - 编辑时,嵌套模型不引用预先存在的对象。它根据请求在控制器的edit 方法中构建一些空对象,但不保存它们,因此它们仅在表单中可用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 2017-04-08
    • 2020-09-16
    相关资源
    最近更新 更多