如何使用 Cocoon 同时创建父元素和嵌套元素

How to create both a parent and nested elements at once with cocoon

我有一个 Edition 模型,它接受 Content 模型的嵌套属性。无论如何,我可以在创建新版本的同时创建嵌套内容吗?

创建版本时,出现错误:

Contents edition can't be blank

据我了解,这是因为版本还没有创建,所以没有edition_id进入内容table。

我尝试在版本和内容模型中设置 inverse_of 选项,但没有成功。我仍然收到此错误。

这是我的版本和内容模型:

class Content < ApplicationRecord
  validates_presence_of :heading, 
                        :link, 
                        :edition_id, 
                        :section_id

  belongs_to :edition, inverse_of: :contents
  belongs_to :section
  belongs_to :source, inverse_of: :contents
end

class Edition < ApplicationRecord
  validates_presence_of :date, :product_id

  belongs_to :product
  has_many :contents, dependent: :destroy, inverse_of: :edition
  has_many :sections, -> { distinct }, through: :contents

  accepts_nested_attributes_for :contents,
                                allow_destroy: true,
                                reject_if: lambda { |attrs| attrs['link'].blank? }
end

我该如何解决这个问题?

编辑:

创建版本时的服务器日志是:

Started POST "/editions" for 127.0.0.1 at 2018-08-02 15:47:49 +0530
Processing by EditionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"QqSMYoMC76mCLPc6LI2ZvAyDih99J6erizPr2+CzAmLDCx3GALccQdLqbDoNaPNza1UAm8m62a8uHQdTwHV3AQ==", "edition"=>{"date(1i)"=>"2018", "date(2i)"=>"8", "date(3i)"=>"1", "product_id"=>"1", "contents_attributes"=>{"1533205044547"=>{"_destroy"=>"false", "heading"=>"Heading 2", "body"=>"<p>Text 12</p>", "section_id"=>"1", "link"=>"https://www.example.com/heading_2", "top_story"=>"0"}}}, "files"=>"", "commit"=>"Create Edition"}
  User Load (1.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" =  ORDER BY "users"."id" ASC LIMIT   [["id", 1], ["LIMIT", 1]]
   (1.2ms)  BEGIN
  Product Load (1.3ms)  SELECT  "products".* FROM "products" WHERE "products"."id" =  LIMIT   [["id", 1], ["LIMIT", 1]]
  Source Load (1.0ms)  SELECT  "sources".* FROM "sources" WHERE "sources"."domain" =  ORDER BY "sources"."id" ASC LIMIT   [["domain", "www.example.com"], ["LIMIT", 1]]
  Section Load (0.9ms)  SELECT  "sections".* FROM "sections" WHERE "sections"."id" =  LIMIT   [["id", 1], ["LIMIT", 1]]
   (1.5ms)  ROLLBACK

编辑 2:

EditionsController 创建操作和 edition_params 方法:

def create
  @edition = Edition.new(edition_params)

  respond_to do |format|
    if @edition.save
      format.html { redirect_to @edition, notice: 'Edition was successfully created.' }
      format.json { render :show, status: :created, location: @edition }
    else
      format.html { render :new }
      format.json { render json: @edition.errors, status: :unprocessable_entity }
    end
  end
end

def edition_params
  params.require(:edition).permit(:date, 
                                  :clicks, 
                                  :product_id,
                                  contents_attributes: [:id,
                                                        :heading,
                                                        :body,
                                                        :link,
                                                        :top_story,
                                                        :section_id,
                                                        :_destroy
                                                       ]
                                 )
end

您可以在关联中添加 optional: true 这将解决您的错误,就像这样

belongs_to :edition, optional: true

到目前为止,我猜你必须先为 nested attributes 构建对象,即

def new
  @edition = Edition.new
  contents = @edition.contents.build
end

并在 create 行动中

def create
  @edition = Edition.new(edition_params)

  respond_to do |format|
    if @edition.save
      format.html { redirect_to @edition, notice: 'Edition was successfully created.' }
      format.json { render :show, status: :created, location: @edition }
    else
      format.html { render :new }
      format.json { render json: @edition.errors, status: :unprocessable_entity }
    end
  end
end

def edition_params
  params.require(:edition).permit(:date, 
                                  :clicks, 
                                  :product_id,
                                  contents_attributes: [:id,
                                                        :heading,
                                                        :body,
                                                        :link,
                                                        :top_story,
                                                        :section_id,
                                                        :_destroy
                                                       ]
                                 )
end

删除 edition_id

的验证
class Content < ApplicationRecord
  validates_presence_of :heading, 
                        :link, 
                        :section_id

  belongs_to :edition, inverse_of: :contents
  belongs_to :section
  belongs_to :source, inverse_of: :contents
end