0

I would like on the form page for a campaign for a user to be able to create cities as well. I followed http://railscasts.com/episodes/196-nested-model-form-part-1?view=comments and https://medium.com/karuna-sehgal/building-a-rails-app-using-tdd-devise-omniauth-and-nested-forms-f7b9769ba2ae (this one uses devise) but cant seem to get it to work.

The error I get is: ActiveRecord::RecordInvalid: Validation failed: Cities campaign must exist

Can anyone tell me what's wrong?

Models:

class City < ApplicationRecord
  belongs_to :campaign#, optional: true
end

class Campaign < ApplicationRecord
  has_many :cities, :dependent => :destroy
  belongs_to :user
  accepts_nested_attributes_for :cities, allow_destroy: true, reject_if: :all_blank
end

Controller:

  def new
    @campaign = current_user.campaigns.build
    3.times { @campaign.cities.build }
  end

  def create
    #binding.pry
    @campaign = current_user.campaigns.build  campaign_params
    binding.pry
    if @campaign.save
      flash[:notice] = "#{@campaign.name} created"
      redirect_to @campaign
    else
      flash[:notice] = "#{@campaign.name} not created"
      redirect_to @campaign
    end
  end

  private

  def campaign_params
    params.require(:campaign).permit(:name, :titles, :sentences, :keywords, cities_attributes: [:name, :phone_number, :zip_code])
  end

Form:

<%= form_for @campaign do |f| %>
  <%= f.label "Name" %>
  <br />
  <%= f.text_field :name %>
  <br /> <br />

  <%= f.label "Titles" %>
  <br />
  <%= f.text_area :titles, cols: 80, rows: 20 %>
  <br /> <br />

  <%= f.label "Sentences" %>
  <br />
  <%= f.text_area :sentences, cols: 80, rows: 20 %>
  <br /> <br />

  <%= f.label "Keywords" %>
  <br />
  <%= f.text_area :keywords, cols: 80, rows: 20 %>
  <br /> <br />

  <%= f.fields_for :cities do | city_form | %>
    <%= city_form.label :name %>
    <%= city_form.text_field :name%>
    <%= city_form.label :phone_number %>
    <%= city_form.text_field :phone_number %>
    <%= city_form.label :zip_code %>
    <%= city_form.text_field :zip_code %>
    </br>
  <% end %>

  <%= f.submit "Submit" %>
<% end %>
1
  • I also need the edit and update functions to work so I cant do class City < ApplicationRecord belongs_to :campaign, optional: true end Commented Mar 25, 2018 at 1:56

2 Answers 2

1

You can use :inverse_of like this:

Active Record provides the :inverse_of option so you can explicitly declare bi-directional associations:

class City < ApplicationRecord
  belongs_to :campaign, inverse_of: :cities
end

class Campaign < ApplicationRecord
  has_many :cities, inverse_of: :campaign
end
Sign up to request clarification or add additional context in comments.

2 Comments

Hey Fongfan this solution works. The issue but I'm facing a new issue. When I go to edit it duplicates the city instead of editing it. Here is what I have for editing. I had to take out the @ symbols for it to allow me to post this. def edit campaign = Campaign.find params[:id] cities = campaign.cities end def update # put for edit campaign = Campaign.find params[:id] if campaign.update_attributes campaign_params flash[:notice] = "#{campaign.name} updated" redirect_to campaign else render :show end end
Hi @DanielRusu you have to permit :id in the cities_attributes like this: “cities_attributes: [:id, :name, :phone_number, :zip_code]”
0

It seems you have missed out to pass campaign_id inside cities_attributes error happened because when rails tried to save inside the cities active_record there were no campaign_id that's why you are getting a validation error like:

ActiveRecord::RecordInvalid: Validation failed: Cities campaign must exist

So you can change campaign_params as follows:

def campaign_params
  params.require(:campaign).permit(:name, :titles, :sentences, :keywords, cities_attributes: [:campaign_id, :name, :phone_number, :zip_code])
end 

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.