0

I have this controller

class PeopleController < ApplicationController
    def new
        @person = Person.new
        @person.phones.new
    end

    # this is the action that gets called by the form
    def create
        render text: person_params.inspect
#       @person = Person.new(person_params)
#       @person.save

#       redirect_to people_path
    end

    def index
        @person = Person.all
    end

private

    def person_params
        params.require(:person).permit(:name, phones_attributes: [ :id, :phone_number ])
    end

end

and this view

<%= form_for :person, url: people_path do |f| %>
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>

  <%= f.fields_for :phones do |f_phone| %>
    <div class="field">
      <p>
        <%= f_phone.label :phone_number %><br />
        <%= f_phone.text_field :phone_number %>
      </p>
    </div>
    <% end %>

  <p>
    <%= f.submit %>
  </p>
<% end %>

When I fill out both form fields and hit "Save Person" I only get {"name"=>"foo"} - the phone number seems to vanish.

However, when I change phones_attributes to phones I get {"name"=>"foo", "phones"=>{"phone_number"=>"123"}} (this would however cause problems with the create function.

What's wrong here?

Please note that this question is strongly related to that one: accepts_nested_attributes_for: What am I doing wrong as well as to this posting: https://groups.google.com/forum/#!topic/rubyonrails-talk/4RF_CFChua0

Community
  • 1
  • 1
speendo
  • 13,045
  • 22
  • 71
  • 107

2 Answers2

0

You don't have @phones defined in the controller:

 def new
    @person = Person.new
    @phones = @person.phones.new
 end
Daiku
  • 1,237
  • 11
  • 20
  • do I need an instance variable for phones? this however wouldn't make the controller save the phone number – speendo Jul 12 '13 at 19:56
  • If you want your view to have access to it, you need to make the instance variable available in the controller. When you say `f.fields_for :phones`, that means use the `@phones` instance variable. – Daiku Jul 12 '13 at 20:00
  • ok, I didn't know that, thank you. However, I think in this case `def new` is not even touched, but `render text: person_params.inspect` wouldn't return the number I entered. – speendo Jul 12 '13 at 20:09
  • 1
    `def new` is touched when you initiate the object. But you are correct that you need to load it again from the database when your action gets called. You didn't indicate which action in your controller is rendering the form in question. – Daiku Jul 12 '13 at 22:00
  • I guess you're not trying to display current values in the view. What comes back in `params[]`? – Daiku Jul 13 '13 at 02:01
  • in principle I try to store values to the database. `render text: person_params.inspect` is just here for debugging. Leaving the code as it is `create` outputs something like `{"name"=>""}`, although it *should* also output some values for `phones`. – speendo Jul 13 '13 at 07:20
0

Finally found the problem. In the view there should be

<%= form_for @person, url: people_path do |f| %>

Instead of

<%= form_for :person, url: people_path do |f| %>

@phron said that already here: accepts_nested_attributes_for: What am I doing wrong

Community
  • 1
  • 1
speendo
  • 13,045
  • 22
  • 71
  • 107