0

I have two models, Countries and Regions. I'm trying to set regions to be a nested attribute of countries. My code so far writes the country to the database, but it does not write the region. I get no errors.

One other thing I'm unsure of in terms of the relationship, should a user be adding a region with country nested, or the other way round with a user adding a country with the region nested?

country.rb

class Country < ApplicationRecord
  has_many :regions, inverse_of: :country
  has_many :roasts
  accepts_nested_attributes_for :regions

  validates :name, presence: true
end

region.rb

class Region < ApplicationRecord
  belongs_to :country, inverse_of: :region

  validates :name, uniqueness: true
  validates :name, presence: true
end

country_controller.rb

def country_params
  params.require(:country).permit(:name, :description, regions_attributes: [:id, :name, :description])
end

country/_form.html.rb

<%= form_with(model: country, local: true) do |form| %>
  <% if country.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(country.errors.count, "error") %> prohibited this country from being saved:</h2>

      <ul>
      <% country.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.label :name %>
    <%= form.text_field :name, id: :country_name %>
  </div>

  <div class="field">
    <%= form.label :description %>
    <%= form.text_field :description, id: :country_description %>
  </div>
      //nested region form
      <%= form.fields_for :region do |region| %>
    <p>
        Region: <%= region.text_field :name %>
    </p>
    <% end %>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

Update

Region isn't a permitted parameter. Checking the controller, I have it as a parameter?

  Parameters: {"utf8"=>"✓", "authenticity_token"=>"wUtZvA8rMeQ12onWg+B4OcbzGzZOIDOLwi99Aef3SnjAg5yyYA0qI8wNJIl41u/S0+RIlMAvkVwWVyWWPF3Ocg==", "country"=>{"name"=>"Guatemala", "description"=>"", "region"=>{"name"=>"Candelaria"}}, "commit"=>"Create Country"}
Unpermitted parameter: :region
   (0.1ms)  BEGIN
  SQL (0.8ms)  INSERT INTO "countries" ("name", "description", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "Guatemala"], ["description", ""], ["created_at", "2018-02-02 22:21:24.093876"], ["updated_at", "2018-02-02 22:21:24.093876"]]
   (0.3ms)  COMMIT
Redirected to http://localhost:3000/countries/10
Completed 302 Found in 5ms (ActiveRecord: 1.2ms)

Update 2

I am now getting regions param allowed, but it seems I'm not actually sending any instruction to create the region. I've therefore added:

  def new
    @country = Country.new
    @country.region.build  //doesn't work
    @country.regions.build //doesn't work
    @country.build_region  //doesn't work
    @country.build_regions //doesn't work
  end

but this just produces the error undefined method 'build' for nil:NilClass

3 Answers 3

1

I would change:

<%= form.fields_for :region do |region| %>
  <p>
    Region: <%= region.text_field :name %>
  </p>
<% end %>

with

<%= form.fields_for :regions do |region| %>
  <p>
    Region: <%= region.text_field :name %>
  </p>
<% end %>

or

<%= form.fields_for country.regions.build do |region| %>
  <p>
    Region: <%= region.text_field :name %>
  </p>
<% end %>
Sign up to request clarification or add additional context in comments.

2 Comments

Hey Pablo. Have updated the form to regions but as per Update to in OP., I realised I hadn't actually been instructing the code to write to that field. That said, I get a new error undefined method build
Well. @country.regions.build should work. :) I don't see anything wrong.
0

You set up your view & strong parameters to support a has_one :region association. has_many :regions has some gotchas. You can try cocoon, Nested forms in rails - accessing attribute in has_many relation

4 Comments

doesn't look like region is a permitted paramater. put the log output in OP
What you try to do and what I answered is for has_one :region association. If you change that it will work. For has_many :regions you have to do country.regions.build hand handle differently in strong params.
@SimonCooper update the answer for has_one :region association.
@SimonCooper Completely changed the answer. Hope it helps
0

Update

<%= form.fields_for :region do |region| %>

to

<%= form.fields_for :regions do |region| %>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.