Reputation: 1456
I have ActiveRecord with a subclass and its associated with another ActiveRecord object. I am able to create my object with nested attributes with a form with nested attributes no problem for a new object (following Ryan Bates rails cast - Thanks by the way :)). However when i do an update it fails to save the changes to either the main object or the related object when submitted
I have the following Activerecord classes and sub class.
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
And the sub class is
class BigRoom < Room
end
And the related class is
class RoomHeader < ActiveRecord::Base
attr_accessible :key, :room_id, :value
belongs_to :room
end
In my room controller I created the nested objects. note that i'm using :type to specify the subclass 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])
...
The form used for creating and editing is the same
<%= 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 &>
And the _room_headers.html.erb partial is
<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>
To recap on the problem. I can successfully create a new BigRoom. In the new form when i create the BigRoom and I can successfully set values for the RoomHeader class and these are all saved successfully.
However when i Edit the the record and submit changes for update, nothing is saved. Either for changes for the Bigroom attributes or to the associated RoomHeader records.
Upvotes: 0
Views: 1304
Reputation: 1456
Ok, nested attributes were a red herring. The problem is with STI
The Rails form helper guide says you can’t rely on record identification with STI.
In the form_for we need to coearce the ids to be the base type id otherwise the edit fails
so
<%= form_for(@room) do |f| %>
should be
<%= form_for(@room.becomes(Room) do |f| %>
if you look at the difference in the html output
the problem html would create ids like big_room_fieldname when in edit mode when using .becomes we get ids like room_fieldname. in whihc case it saves and updates ok
Upvotes: 0
Reputation: 1071
first try by
if @room.update_attribute(params[:room])
rather
if @room.update_attributes(params[:room])
if this works then their are some errors with your validdations
Upvotes: 0