茧gem是否需要在controller new action中构建n个模型?

Does the cocoon gem require n models to be built in the controller new action?

我完全按照描述在我的 rails 4 应用程序中安装了 cocoon gem。这在父模型表单中非常有效,允许用户为子模型添加 add/remove 字段。我遇到麻烦的地方是子对象的提交。如果子模型在父模型的新操作中是 built,那么无论创建了多少模型,我都可以提交,仅此而已。这从提交的参数中显而易见,因为它们包含 child_attributes(或者不包含,如果控制器中没有子模型 built)。

目前运行

rails 4.2.10

ruby2.5.1

茧 1.2.14

jquery-rails 4.3.3

jquery-ui-rails6.0.1

代码片段

class EventsController < ApplicationController
  before_action :authenticate_user!, only: [:new, :create]

  def new
    @event = Event.new
    @event.competitions.build
  end

  def create
    @event = current_user.events.create(event_params)
    if @event.valid?
      flash[:notice] = "Event created"
      redirect_to events_path
    else
      flash[:alert] = "Event not created.  Please check for errors in the form and try again."
      render :new, status: :unprocessable_entity
    end
  end

def event_params
    params.require(:event).permit(
                                  :event_name,
                                  :event_start,
                                  :event_end,
                                  :event_address,
                                  competitions_attributes: [:id, :competition_name, :maximum_participants, :type_id, :fee, :_destroy]
    )
  end
end

父模型

  acts_as_paranoid
  has_and_belongs_to_many :users
  has_many :competitions, dependent: :destroy, inverse_of: :event
  belongs_to :address
  accepts_nested_attributes_for :address
  accepts_nested_attributes_for :competitions, allow_destroy: true

童模

class Competition < ActiveRecord::Base
  acts_as_paranoid
  belongs_to :event
  has_many :participants, dependent: :destroy
  belongs_to :type
  accepts_nested_attributes_for :participants, allow_destroy: true  

表格 (new.html.erb)

  <div class="text-left ">
    <%= simple_form_for @event do |f| %>
        <%= f.input :event_name, input_html: {maxlength: 60} %>
        <%= f.input :logo, label: "Event Logo:", hint: 'jpg or png files allowed, max size: 1MB' %>
        <a <%= f.input :description, label_html: {class: "glyphicon glyphicon-question-sign event-new", href: "#", 'data-content': "You can format your description using the editor buttons. Cutting and pasting from other text editors will not work unless they are first exported into html format. For security reasons, some html tags are not allowed and will be removed.", rel: "popover", "data-placement": 'top', 'data-original-title': 'WYSIWYG editor help', 'data-trigger': 'hover' }, as: :ckeditor, input_html: { ckeditor: { toolbar: 'mini' } } %></a>
        <%= f.input :event_address, placeholder: "Enter Street Address, City, State, Postal Code" %>
        <%= f.input :registration_fee, :input_html => { :value => '0.00'}, label: "Team registration fee" %>


        <%= f.input :event_start %>
        <%= f.input :event_end %>
        <br />
        <h3>Competitions</h3>
        <div id="competitions">
          <%= f.simple_fields_for :competitions do |competition| %>
            <%= render 'competition_fields', f: competition %>
          <% end %>
          <div class="links">
            <%= link_to_add_association 'add competition', f, :competitions %>
          </div>
        </div>

        <%= f.submit 'Create', :class => 'pull-right btn btn-primary' %>
    <% end %>
  </div

部分(命名为 _competition_fields.html.erb

<div class="nested-fields">
  <%= f.input :competition_name %>
  <%= f.collection_select(:type_id, @types, :id, :name, prompt: "Select a Type") %>
  <%= f.input :fee, :input_html => { :value => '0.00'} %>
  <%= f.input :maximum_participants %>
  <%= link_to_remove_association "Delete Competition", f %>
</div>

application.js

//= require jquery
//= require bootstrap-sprockets
//= require jquery_ujs
//= require dataTables/jquery.dataTables
//= require jquery-ui/widgets/autocomplete
//= require autocomplete-rails
//= require moment
//= require bootstrap-datetimepicker
//= require ckeditor/init
//= require google_analytics
//= require cocoon
//= require_tree .

从Rails控制台(插入父模型后)

"competitions_attributes"=>{"0"=>{"competition_name"=>"test1", "type_id"=>"2", "fee"=>"0.00", "maximum_participants"=>"8", "_destroy"=>"false"}}}, "commit"=>"Create"}

  SQL (17.4ms)  INSERT INTO "competitions" ("competition_name", "maximum_participants", "type_id", "fee", "event_id", "created_at", "updated_at") VALUES (, , , , , , ) RETURNING "id"  [["competition_name", "test1"], ["maximum_participants", 8], ["type_id", 2], ["fee", "0.0"], ["event_id", 305], ["created_at", "2019-08-01 11:13:44.582299"], ["updated_at", "2019-08-01 11:13:44.582299"]]

我已经解决了 gem 设置的所有常见问题(accepts_nested_attributes_for、inverse_of、child_fields 部分的命名和缩进, jQuery 已安装并调用了 cocoon 等)据我所知,这一切都符合规范。只要子模型在新动作中是 built,它就可以工作。

啊!真是一个面面相觑的时刻。事实证明,ckeditor 描述字段中的 <a> 标签导致了所有这些大惊小怪。删除 <a> 标签允许 cocoon 正常运行。

因此,在回答最初的问题时:不,茧 gem 甚至不需要在新的控制器操作中构建一个子模型来添加它们。