如何在一个表单中为多个模型使用嵌套表单?

时间:2010-05-06 15:06:26

标签: ruby-on-rails

我正在努力想出一个正确的方法来设计一个允许我为两个不同模型输入数据的表单。该表单用于“事件”,具有以下关系:

belongs_to              :customer
belongs_to              :user

has_one                 :incident_status

has_many                :incident_notes
accepts_nested_attributes_for :incident_notes, :allow_destroy => false

因此,事件被分配给“客户”和“用户”,并且用户可以向事件添加“注释”。我在表格的笔记部分遇到了麻烦。这里是如何提交表单的:

{"commit"=>"Create",
 "authenticity_token"=>"ECH5Ziv7JAuzs53kt5m/njT9w39UJhfJEs2x0Ms2NA0=",
 "customer_id"=>"4",
 "incident"=>{"title"=>"Something bad",
 "incident_status_id"=>"2",
 "user_id"=>"2",
 "other_id"=>"AAA01-042310-001",
 "incident_note"=>{"note"=>"This is a note"}}}

似乎是尝试将incident_note添加为“突发事件”下的字段,而不是在incident_note表中创建一个新条目,其中一个event_id外键链接回事件。

以下是'IncidentNote'模型:

belongs_to :incident
belongs_to :user

以下是“事件”的表单:

<% form_for([@customer,@incident]) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :other_id, "ID" %><br />
    <%= f.text_field :capc_id %>
  </p>
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
    <p>
      <%= label_tag 'user', 'Assign to user?' %>
      <%= f.select :user_id, @users.collect {|u| [u.name, u.id]} %>
    </p>
    <p>
      <%= f.label :incident_status, 'Status?' %>
      <%= f.select :incident_status_id, @statuses.collect {|s| [s.name, s.id]} %>
    </p>
    <p>
      <% f.fields_for :incident_note do |inote_form| %>
        <%= inote_form.label :note, 'Add a Note' %>
        <%= inote_form.text_area :note, :cols => 40, :rows => 20 %>
      <% end %>
    </p>
  <p>
    <%= f.submit "Create" %>
  </p>
<% end %>

最后,这里是New和Create的incident_controller条目。

新:

  def new
    @customer = current_user.customer
    @incident = Incident.new
    @users = @customer.users
    @statuses = IncidentStatus.find(:all)
    @incident_note = IncidentNote.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @incident }
    end
  end

创建:

  def create
    @users = @customer.users
    @statuses = IncidentStatus.find(:all)
    @incident = Incident.new(params[:incident])
    @incident.customer = @customer
    @incident_note = @incident.incident_note.build(params[:incident_note])
    @incident_note.user = current_user

    respond_to do |format|
      if @incident.save
        flash[:notice] = 'Incident was successfully created.'
        format.html { redirect_to(@incident) }
        format.xml  { render :xml => @incident, :status => :created, :location => @incident }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @incident.errors, :status => :unprocessable_entity }
      end
    end
  end

我不确定在哪里看这一点。我确信这只是我当前Rails技能的限制(我不太了解)。因此,如果有人能指出我正确的方向,我将非常感激。如果需要更多信息,请告诉我们!

谢谢!

1 个答案:

答案 0 :(得分:1)

检查api是否为fields_for方法并滚动到一对多部分。

您的模型有很多:incident_notes,而不是一个incident_note,这就是为什么它不理解关系并尝试查找具有此名称的字段。

所以它应该是:

  <% f.fields_for :incident_notes do |inote_form| %>
    <%= inote_form.label :note, 'Add a Note' %>
    <%= inote_form.text_area :note, :cols => 40, :rows => 20 %>
  <% end %>

它遍历分配给事件的所有incident_notes并为每个事件生成字段 您还必须在new动作中至少构建一个音符,否则将不会:

  def new
    @incident = Incident.new
    @incident.incident_notes.build
    # ...
  end