Rails 关联模型表单

Rails Associated Model Forms

我有模型

influencers (id, name, ...)
social_accounts (id, name, ....)
influencer_accounts (id, influencer_id, social_account_id, name, url)

当我创建一个有影响力的人时,我得到 7 social_accounts,我需要为其输入有影响力的帐户的详细信息。有没有一种方法可以通过循环从视图中为 influencers has_many influencer_accounts 构建表单?

我尝试了什么?

model/influencer.rb

class Influencer < ApplicationRecord

  # Associations
  has_many :influencer_accounts

  accepts_nested_attributes_for :influencer_accounts , :allow_destroy => true, reject_if: proc { |attributes| attributes['account_url'].blank? }


end

model/influencer_accounts.rb

class InfluencerAccount < ApplicationRecord

  # Associations
  belongs_to :influencer
  belongs_to :social_account

end

influencers_controller.rb

  def new
    @influencer = Influencer.new
    # @influencer.influencer_accounts.build

    @social_accounts = SocialAccount.all
  end


  def create
    # render json: params
    @influencer = Influencer.new(influencer_params)

    if @influencer.save
      redirect_to @influencer, notice: 'Influencer was successfully created.'
    else
      @social_accounts = SocialAccount.all
      render :new
    end

  end

views/influencers/new.html.erb

<% content_for :title, "New Influencer" %>

<div class="bg-light lter b-b wrapper-md">
    <h1 class="m-n font-thin h3">New Influencer</h1>
</div>

<div class="wrapper-md">

    <%= render 'partials/flash_message' %>

    <div class="panel panel-default">
        <div class="panel-heading font-bold">
            New Influencer
        </div>
        <div class="panel-body">
            <%= nested_form_for @influencer, url: influencers_path, :html => {:multipart => true, :class => 'form-horizontal'} do |f| %>

            <div class="form-group <%= 'has-error' if (@influencer.errors[:first_name].present? or @influencer.errors[:last_name].present?) %>">
                <%= f.label :first_name, "Name", :class => 'col-sm-2 control-label' %>
                <div class="col-sm-3">
                    <%= f.text_field :first_name, :class => 'form-control' %>
                    <%= show_errors(@influencer, :first_name).html_safe %>
                </div>
                <div class="col-sm-3">
                    <%= f.text_field :last_name, :class => 'form-control' %>
                    <%= show_errors(@influencer, :last_name).html_safe %>
                </div>
            </div>
            <div class="line line-dashed b-b line-lg pull-in"></div>

            <div class="form-group <%= 'has-error' if @influencer.errors[:email].present? %>">
                <%= f.label :email, "Email Address", :class => 'col-sm-2 control-label' %>
                <div class="col-sm-6">
                    <%= f.text_field :email, :class => 'form-control' %>
                    <%= show_errors(@influencer, :email).html_safe %>
                </div>
            </div>
            <div class="line line-dashed b-b line-lg pull-in"></div>

            <div class="form-group <%= 'has-error' if @influencer.errors[:phone].present? %>">
                <%= f.label :phone, "Phone Number", :class => 'col-sm-2 control-label' %>
                <div class="col-sm-6">
                    <%= f.text_field :phone, :class => 'form-control' %>
                    <%= show_errors(@influencer, :phone).html_safe %>
                </div>
            </div>
            <div class="line line-dashed b-b line-lg pull-in"></div>

            <div class="form-group">
                <label class="col-sm-2 control-label">Social Networks</label>
                <div class="col-sm-10">
                  <div id="social-accounts">
                    <% @social_accounts.each do |social_account| %>

                      <%= f.fields_for :influencer_accounts do |ia| %>
                      <div class="row">

                        <div class="col-sm-3">
                          <%= ia.collection_select(:social_account_id, @social_accounts, :id, :name, { :prompt => false, :selected => social_account.id }, {:class => 'form-control' }) %>
                        </div>

                        <div class="col-sm-5">
                          <div class="input-group m-b">
                            <%= ia.text_field :account_url, :class => 'form-control' %>
                            <span class="input-group-btn">
                              <a class="btn btn-default remove"><span class="text-danger"><i class="fa fa-times"></i></span></a>
                              <%= ia.link_to_remove "Remove this task" %>
                            </span>
                          </div>
                        </div>


                      </div>
                      <% end %>
                    <% end %>
                  </div>

                  <p><%= f.link_to_add "Add a account", :influencer_accounts, "data-target" => "#social-accounts", class: "btn btn-info btn-xs" %></p>
                </div>
            </div>
            <div class="line line-dashed b-b line-lg pull-in"></div>


                <div class="form-group">
                    <div class="col-sm-4 col-sm-offset-2">
                        <%= f.submit 'Create Influencer', :class => 'btn btn-primary' %>
                    </div>
                </div>

            <% end %>
        </div>
    </div>
</div>

在我尝试提交后 - 表单未保存并且 returns 返回重复字段

你应该使用 cocoon gem 为此,您还应该使用 nested form gem