我有一个子类的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记录。
答案 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的情况下,它保存并更新确定