如何使用茧一次创建父元素和嵌套元素

时间:2018-08-02 10:12:17

标签: ruby-on-rails ruby-on-rails-5 cocoon-gem

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

创建版本时,它给我错误:

Contents edition can't be blank

根据我的阅读,这是因为尚未创建该版本,因此,没有edition_id可以输入到内容表中。

我尝试在版本和内容模型中都设置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" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (1.2ms)  BEGIN
  Product Load (1.3ms)  SELECT  "products".* FROM "products" WHERE "products"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Source Load (1.0ms)  SELECT  "sources".* FROM "sources" WHERE "sources"."domain" = $1 ORDER BY "sources"."id" ASC LIMIT $2  [["domain", "www.example.com"], ["LIMIT", 1]]
  Section Load (0.9ms)  SELECT  "sections".* FROM "sections" WHERE "sections"."id" = $1 LIMIT $2  [["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

2 个答案:

答案 0 :(得分:1)

据我所知,您必须首先为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

答案 1 :(得分:0)

您可以添加可选:true关联,这样可以解决您的错误,

belongs_to :edition, optional: true