使用另一个嵌套子项(AssociationTypeMismatch)为嵌套子项提交AJAX表单

时间:2012-05-21 09:03:47

标签: ruby-on-rails-3 forms activerecord

我的模特

我正在尝试为 Annotation 创建表单。此注释属于 Map ,每个注释应具有一个 Boundary 。地图可以有很多注释。

我首先通过让注释 Map has_one Boundary 来创建关联,但后来我转而使用多态boundary_object。无论如何错误都是一样的。

has_one :boundary, :as => :boundary_object         # <= Map
has_one :boundary, :as => :boundary_object         # <= Annotation
belongs_to :boundary_object, :polymorphic => true  # <= Boundary

视图和控制器

这就是事情:首先我使用Boundary.new在这里创建一个新的边界对象,因为我没有预先设定的注释对象,因为表格可以多次提交。

maps/show.html.erb

<%= form_for([@map, Annotation.new], :remote => true ) do |f| %>
    <%= f.text_area :body, :cols => 80, :rows => 10, :style => "width: 500px" %>
    <%= f.fields_for Boundary.new do |b| %>
      <%= b.text_field :ne_x, :style => "display:none" %>
      <%= b.text_field :ne_y, :style => "display:none" %>
      <%= b.text_field :sw_x, :style => "display:none" %>
      <%= b.text_field :sw_y, :style => "display:none" %>
    <% end %>
<% end %>

我也可以使用f.fields_for :boundary,如果我在maps_controller.rb

中有此功能
@annotation = @map.annotations.build
@annotation.boundary = Boundary.new

但结果仍然相同。

annotations_controller.rb

def create
  @annotation = Annotation.new(params[:annotation])
  respond_to do |format|
    if @annotation.save
      format.js { }
  end
end

错误

提交该表单时,会导致create方法第一行出现以下错误。

  

ActiveRecord :: AssociationTypeMismatch(边界(#2158793660)预期,获得ActiveSupport :: HashWithIndifferentAccess(#2165684420))

显然,表单在没有整个边界的情况下工作。这些是提交的参数:

{
  "utf8"=>"✓",
  "authenticity_token"=>"6GDF6aDc6GMR3CMP+QzWKZW9IV9gSxfdkxipfg39q7U=",
  "annotation"=>
  {
    "body"=>"foo bar",
    "boundary"=>
    {
      "ne_x"=>"11312", 
      "ne_y"=>"5919", 
      "sw_x"=>"6176", 
      "sw_y"=>"1871"
    }
  }, 
 "map_id"=>"1"
}

我需要做些什么才能立即为此注释创建 Boundary 对象?

1 个答案:

答案 0 :(得分:1)

根据您的协会:

首先,您需要构建一个新的边界对象(有关详细信息,请参阅here):

def show
  @map = ...
  @annotation = @map.annotations.build
  @boundary = @annotation.build_boundary # build new boundary
end

第二次,您需要修改视图:

<%= form_for([@map, @annotation], :remote => true ) do |f| %>
  <%= f.text_area :body, :cols => 80, :rows => 10, :style => "width: 500px" %>
  <%= f.fields_for :boundary do |b| %>
    ...
  <% end %>
<% end %>

第三次,检查您是否在注释模型中为您的边界 accepted_nested_attributes_for

accepts_nested_attributes_for :boundary

表单将如下所示 - 请注意,关联的名称需要_attributes

<input … name="annotation[boundary_attributes][ne_x]" … />