如何获得Rails构建和fields_for只创建一个新记录而不包括现有记录?

Jas*_*ten 32 ruby-on-rails

我正在使用build,fields_foraccepts_nested_attributes_for在与新注册相同的表格上创建新的注册说明(有许多注册说明).大.

问题:在现有注册的编辑表单上,我想要创建另一个新注册注释,但我不希望看到每个现有注册注释的字段.

我有这个

class Registration < ActiveRecord::Base
  attr_accessible :foo, :bar, :registration_notes_attributes
  has_many :registration_notes
  accepts_nested_attributes_for :registration_notes
end
Run Code Online (Sandbox Code Playgroud)

还有这个

class RegistrationsController < ApplicationController
  def edit
    @registration = Registration.find(params[:id])
    @registration.registration_notes.build
  end
end
Run Code Online (Sandbox Code Playgroud)

在我看来我这样做:

<%= form_for @registration do |r| %>
  <%= r.text_field :foo %>
  <%= r.text_field :bar %>
  <%= r.fields_for :registration_notes do |n| %>
    <%= n.text_area :content %>
  <% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

并且它创建一个新的注册说明(良好)空白文本区域每个现有注册注意对于注册(不,谢谢).

有没有办法只为该注册创建一个新注释并将现有注释单独留下?

Zai*_*uch 74

编辑:我之前的回答(见下文)是困扰我,因为它不是很好(它仍然registration_notes不必要地循环所有其他).在阅读了API之后,获得OP所需行为的最佳方法是替换:

<%= r.fields_for :registration_notes do |n| %>
Run Code Online (Sandbox Code Playgroud)

有:

<%= r.fields_for :registration_notes, @registration.registration_notes.build do |n| %>
Run Code Online (Sandbox Code Playgroud)

fields_for可选地接受第二个参数,该参数是要传递给构建器的特定对象(请参阅API),该构建器是内联构建的.实际上,在控制器中创建和传递新音符实际上更好,而不是在表单中传递(只是为了将逻辑移出视图).


原始答案(我是如此接近):

只是为了澄清,您希望您的编辑表单包含一个新的嵌套注册注释(并忽略任何其他现有注册注释)?我没有对此进行测试,但您应该可以通过替换:

  <%= r.fields_for :registration_notes do |n| %>
Run Code Online (Sandbox Code Playgroud)

有:

  <%= r.fields_for @registration.registration_notes.build do |n| %>
Run Code Online (Sandbox Code Playgroud)

编辑:好的,从我自己的快速测试不起作用,但你可以这样做:

<%= r.fields_for :registration_notes do |n| %>
  <%= n.text_area :content if n.object.id.nil? %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

如果注册注释的id为nil(即尚未保存),则仅添加文本区域.

此外,我实际上测试了这个,它确实工作;)