0

我有一个带有子类的 ActiveRecord,它与另一个 ActiveRecord 对象相关联。我可以使用具有嵌套属性的表单创建具有嵌套属性的对象,这对于新对象没有问题(遵循 Ryan Bates rails cast - 顺便感谢 :))。但是,当我进行更新时,提交时无法将更改保存到主对象或相关对象

我有以下 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 记录的更改。

4

2 回答 2

0

首先尝试

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

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

如果这可行,那么它们是您的验证的一些错误

于 2012-10-18T10:15:42.567 回答
0

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

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

在 form_for 中,我们需要将 id 强制为基本类型 id,否则编辑会失败

所以

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

应该

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

如果您查看 html 输出的差异

问题 html 在编辑模式下使用 .becomes 时会创建像 big_room_fieldname 这样的 id,我们会得到像 room_fieldname 这样的 id。在这种情况下,它可以保存和更新

于 2012-10-26T10:42:19.137 回答