嵌套对象是ActiveRecord子类时,嵌套属性的更新失败

时间:2012-10-18 09:53:06

标签: ruby-on-rails activerecord subclass nested-attributes

我有一个子类的ActiveRecord,它与另一个ActiveRecord对象相关联。 我能够使用嵌套属性创建我的对象,其中包含具有嵌套属性的表单,对于新对象没有问题(按照Ryan Bates导演 - 感谢方式:))。但是,当我进行更新时,无法在提交时将更改保存到主对象或相关对象

我有以下Activerecord类和子类。

class Room < ActiveRecord::Base

 attr_accessible :name, :type, room_headers_attributes

 has_many :room_headers, dependent: :destroy

 accepts_nested_attributes_for :room_headers , :allow_destroy => true

end

子类是

class BigRoom < Room

end

相关的课程是

class RoomHeader < ActiveRecord::Base

  attr_accessible :key, :room_id, :value

  belongs_to :room
end

在我的房间控制器中,我创建了嵌套对象。请注意,我使用:type来指定子类型

def new
    @room = current_user.passes.build(params[:room])
    @room.type = params[:type]    

    3.times do
        room_header = @room.room_headers.build
      end

    ....
 end

 ....

def edit
  @room = Room.find(params[:id])
end

def update
    @room = Room.find(params[:id])

 if @room.update_attributes(params[:room])
 ...

用于创建和编辑的表单是相同的

<%= form_for(@room) do |f| %>

<div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
</div>

<%= f.fields_for :room_headers do |builder| %>
   <%= render 'room_header_fields', f: builder %>
<% end %>

<div class="actions">

    <%= f.submit %>
  </div> 

<% end &>

_room_headers.html.erb部分是

<p class="fields">
  <%= f.label :key, "Key" %>
  <%= f.text_field :key %>
  <%= f.label :value, "Value" %>
  <%= f.text_field :value %>
  <%= f.check_box :_destroy %>
  <%= f.label :_destroy, "Remove Header" %>
</p>

回顾一下这个问题。我可以成功创建一个新的BigRoom。在我创建BigRoom的新表单中,我可以成功设置RoomHeader类的值,并且这些都已成功保存。

但是,当我编辑记录并提交更新以进行更新时,不会保存任何内容。要么更改Bigroom属性,要么更改为关联的RoomHeader记录。

2 个答案:

答案 0 :(得分:0)

首先尝试

  if @room.update_attribute(params[:room])

     rather
   if @room.update_attributes(params[:room])

如果这样做,那么他们的验证会出现一些错误

答案 1 :(得分:0)

好的,嵌套属性是红鲱鱼。问题在于STI

Rails表单帮助指南说你不能依赖STI的记录识别。

在form_for中我们需要将id同步为基本类型id否则编辑失败

所以

<%= form_for(@room) do |f| %>

应该是

<%= form_for(@room.becomes(Room) do |f| %>

如果你看一下html输出中的差异

问题html会在编辑模式下创建像big_room_fieldname这样的ID 当使用.becomes时,我们会得到像room_fieldname这样的ID。在whihc的情况下,它保存并更新确定