Reputation: 1456
I have a few models setup using STI
Person < ActiveRecod.....
Man
Woman
I've specified a type field and creating a new record works fine. The sub type (Man or Woman) is succesfully saved with the record and the in the type column is the correct type.
However, when i try to update/edit the record it never calls the SQL UPDATE. update_attributes returns true. the log indicates a call to SELECT, but UPDATE is not called.
If I remove the type field from the form. and create new record it saves. but the type field is null. but then i can update the record.
any ideas or works arounds to fix this ?
controller code
# GET /persons/new
# GET /persons/new.json
def new
@person = current_user.persons.build(params[:person])
@person.type = params[:type]
respond_to do |format|
format.html # new.html.erb
format.json { render json: @pass }
end
end
# GET /persons/1/edit
def edit
@person = Person(params[:id])
end
# POST /persons
# POST /persons.json
def create
@person = current_user.persons.build(params[:person])
respond_to do |format|
if @person.save
format.html { redirect_to @person, notice: 'Person was successfully created.' }
format.json { render json: @person, status: :created, location: @pperson }
else
format.html { render action: "new" }
format.json { render json: @person.errors, status: :unprocessable_entity }
end
end
end
# PUT /persons/1
# PUT /persons/1.json
def update
@person = Person.find(params[:id])
respond_to do |format|
if @person.update_attributes(params[:person])
format.html { redirect_to @person, notice: 'Person was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @person.errors, status: :unprocessable_entity }
end
end
end
when i call new it it would be for the sub class i.e
<%= link_to "New Woman", new_woman_path %>
I have routes prepared for this i.e
resources :women, :controller => "persons", :type => "Woman"
resources :men, :controller => "persons", :type => "Man"
when i call edit which is where i have the problem i.e.
<%= link_to 'Edit', edit_person_path(@person) %>
Note that if i create and edit a record in the console. it is created and updated ok.
Upvotes: 0
Views: 248
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(@person) do |f| %> should be
<%= form_for(@person.becomes(Person) do |f| %> if you look at the difference in the html output
the problem html would create ids like edit_woman_fieldname when in edit mode when using .becomes we get ids like edit_room_fieldname. in whihc case it saves and updates ok
Upvotes: 2