1

I created a form using scaffold and then creating Models to make a nested model but I get an error in my browser and I cannot solve it , I am looking for help here, I am getting that error :

    NameError in Clients#new
     line #33 raised:

undefined local variable or method `city' for #<#<Class:0xc4fb5bc>:0xb704f94>

Extracted source (around line #33):

30:     <% end %>
31:   </div>
32:   <div class="field">
33:     <%= city.fields_for :street do |street| %>
34:     <%= street.label :street %>
35:     <%= street.text_field :name %>
36:     <% end %>

Client.rb

class Client < ActiveRecord::Base
  attr_accessible :email, :name
  has_one :city
  accepts_nested_attributes_for :city
end

city.rb

class City < ActiveRecord::Base
  attr_accessible :client_id, :name
  belongs_to :client
  has_many :streets
  accepts_nested_attributes_for :streets
end

street.rb

class Street < ActiveRecord::Base
  attr_accessible :city_id, :name
  belongs_to :city
end

clients_controller.rb [ generated by scaffold ]

def new
    @client = Client.new
    @city = @client.build_city
    @street = @city.build_street # I don't know should I add this line or not

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @client }
    end

  end

the form

<%= form_for(@client) do |f| %>
  <% if @client.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@client.errors.count, "error") %> prohibited this client from being saved:</h2>

      <ul>
      <% @client.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.text_field :email %>
  </div>
  <div class="field">
    <%= f.fields_for :city do |city| %>
    <%= city.label :city %>
    <%= city.text_field :name %>
         <%= city.fields_for :street do |street| %>
    <%= street.label :street %>
    <%= street.text_field :name %>
    <% end %>
    <% end %>
  </div>
  <div class="field">

  </div>

  <div class="actions">
    <%= f.submit "Submit Client", class: "btn btn-large btn-primary" %>
  </div>
<% end %>

routes.rb

 resources :clients do
    resources :cities do
      resources :streets
    end
  end
Mostafa Hussein
  • 11,063
  • 3
  • 36
  • 61

2 Answers2

0

You have to change your model:

class City < ActiveRecord::Base
  attr_accessible :client_id, :name
  belongs_to :client
  has_many :streets
  accepts_nested_attributes_for :streets # add the "s"!
end

And you have to modify your _form.html.erb

<%= city.fields_for :streets do |street| %>  ## add also the "s"
  <%= street.label :street %>
  <%= street.text_field :name %>
<% end %>

And you also have to modify your controller like mind.blank said in his answer.

Btw maybe this help you in general to understand accepts_nested_attributes_for a bit better..

Matthias
  • 4,355
  • 2
  • 25
  • 34
  • I did and I got the following NameError in Clients#new /_form.html.erb where line #29 raised: undefined local variable or method `city' for #<#:0xb9aeed4> Extracted source (around line #29): 26: <% end %> 27: 28:
    29: <%= city.fields_for :street do |street| %> 30: <%= street.label :street %> 31: <%= street.text_field :name %> 32: <% end %>
    – Mostafa Hussein May 04 '13 at 14:52
  • your variable city is not available outside of the loop..try @city? – Matthias May 04 '13 at 15:05
  • thanks :D , it solved , but if i want to add more nested attribute i will follow the same way right ? and when submit i got this error `Can't mass-assign protected attributes: city_attributes` – Mostafa Hussein May 04 '13 at 15:07
  • i added a view helpful links to my answer..check them out to learn more about nested model forms. – Matthias May 04 '13 at 15:10
  • add city_attributes to the attr_accessible in your client model, like described in this question: http://stackoverflow.com/questions/5037239/nested-form-triggering-a-cant-mass-assign-protected-attributes-warning – Matthias May 04 '13 at 15:12
  • how to make my form dropdown list attributes and dynamic ? – Mostafa Hussein May 04 '13 at 15:26
0

Also make sure you use build_association for a has_one association, and associations.build for a has_many.

# has_one :city
@city = @client.build_city

# has_many :streets
@street = @city.streets.build
mind.blank
  • 4,820
  • 3
  • 22
  • 49