有人知道如何以一种形式保存许多对象吗?

发布于 2024-09-28 07:16:25 字数 1432 浏览 0 评论 0原文

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

- 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 帖子。似乎没有什么真正指向专门为一个预先存在的父对象创建新的子对象。

更新:

我的印象是我必须切换parent_object的控制器操作以进行def update

  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 控制器时,不会为其填写参数。哈哈,不知道该怎么办。

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

I am trying to save many new objects in a form to one pre-existing parent object.

- form_for :parent_object do |f|

This is the beginning of my form. And then within it, I would do:

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

Now if I were to save this, it would render as an ParentObject_Controller Update action which would fail because Update doesn't identify new objects.

So if I wanted to render the appropriate Save action, I would have to set up like this :

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

This form then renders the Save action, but only saves the last child_object.

I would show you my controller, but there's hardly a point because its devastatingly erroneous.

My question is, how would you save many new objects in a form to one pre-existing parent object?

I have looked extensively at Ryan Bate's work, and many many other blogs and SO posts regarding this. Nothing seems to really point at specifically creating new child objects for one pre-existing parent object.

Update:

I am under the impression that I have to toggle the parent_object's controller actions for def update.

  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

In debugger, if I I place a debugger at the root of def update, and I write :

>> params[:parent_object]
#=> nil

Interesting! That means that when child_object is send to parent_object controller, the params are not filled out for it. Haha, no idea what to do about it though..

Unfortunately that code doesn't work, it was just my attempt at getting closer. ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一向肩并 2024-10-05 07:16:25

好吧,让我们再试一次。代码取自 RB 的截屏视频,并替换了对象名称:

<% 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 在他的截屏视频中提出的建议。如果您需要进一步的解释,请在评论中告诉我。

-- 编辑 --

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,嵌套实例也将被创建。

我没有在此响应中包含所有模型和控制器代码。您可以通过下载本集的源代码。

OK, let's give it another shot. Code taken from RB's screencast with replaced object names:

<% 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 %>

This is a form for @parent_object that has fields for :child_objects. Of course, you've to replace fields with your own.

To make this work, you'll have to build child objects in the constructor:

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

Similarly in the edit method, you'd do:

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

To make it work, you need to define the nested attributes for child object:

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

Hope this helps - this is exactly what RB proposes in his screencasts. Let me know in the comments if you need some further explanation.

-- EDIT --

The update method in the parent_object_controller.rb is just a standard one:

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

But thanks to the accepts_nested_attributes_for in the ParentObject, the nested instances will be created as well.

I didn't include all the model and controller code in this response. You can see the rest of the code by downloading source code for this episode from github.

歌入人心 2024-10-05 07:16:25

您可以查看我给的这个答案类似的问题。有两种选择:使用单独的表单,或使用单个表单。

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

polymorphic_path([@parent_object, @child_object])

You can take a look at this answer I gave to a similar question. There're two options: with separate forms, or with a single form.

You'll just have to change the moderate_names_path to the correct path to your parent model instance (and of course the set of fields you want to modify). You can do it with polymorphic_path:

polymorphic_path([@parent_object, @child_object])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文