使用设计创建嵌套表单

时间:2018-03-25 01:53:41

标签: ruby-on-rails devise nested-form-for

我希望在表单页面上为用户创建一个能够创建城市的广告系列。我跟着http://railscasts.com/episodes/196-nested-model-form-part-1?view=commentshttps://medium.com/karuna-sehgal/building-a-rails-app-using-tdd-devise-omniauth-and-nested-forms-f7b9769ba2ae(这个使用了设计),但似乎无法让它发挥作用。

我得到的错误是:ActiveRecord :: RecordInvalid:验证失败:城市广告系列必须存在

谁能告诉我什么是错的?

型号:

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

控制器:

  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_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 %>

2 个答案:

答案 0 :(得分:1)

您可以像这样使用:inverse_of

  

Active Record提供:inverse_of选项,因此您可以显式   声明双向关联:

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

class Campaign < ApplicationRecord
  has_many :cities, inverse_of: :campaign
end

答案 1 :(得分:0)

似乎您错过了campaign_id cities_attributes内部发生错误,因为当rails试图在城市内保存active_record时,没有campaign_id这就是为什么你是得到验证错误,如:

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

因此,您可以按如下方式更改campaign_params

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