Pergunta

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.

Foi útil?

Solução

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top