如何同时创建父元素和子元素

How do i create a parent and child element at the same time rails

提问人:GabrielTheCoder 提问时间:9/7/2022 更新时间:9/7/2022 访问量:96

问:

我想同时创建一个和关于。While Invoice 和 InvoiceItem .如何在 Rails 7 中执行此类操作,以便用户可以通过 Turbo 将多个 invoiceItems 添加到他们的发票中?我不需要知道 TurboStreams 和其他东西是如何工作的,因为我很熟悉,但我只是无法让 InvoiceItems 与 Invoice 同时创建。 我已经找到了这篇文章,但无法从中获得任何有用的信息。InvoiceInvoiceItemshas_many :invoice_itemsbelongs_to :invoice

模型

发票.rb

class Invoice < ApplicationRecord
  belongs_to :project
  
  has_many :invoice_items, foreign_key: :invoice_id # not sure if this foreign_key is necessary
  accepts_nested_attributes_for :invoice_items
end

invoice_item.rb

class InvoiceItem < ApplicationRecord
  belongs_to :invoice
end

控制器

Invoice_controller.rb

  def create
    @project = Project.find(params[:project_id])
    @client = Client.find(params[:client_id])
    @invoice = @project.invoices.new(invoice_params)
    @invoice_item = @invoice.invoice_items.new
    @invoice.invoice_items_attributes = [:invoice_id, :amount]

    @invoice.client_id = @client.id

    respond_to do |format|
      if @invoice.save

....

    def invoice_params
      params.require(:invoice).permit(... :invoice_item, invoice_item_attributes: [:id, :invoice_id, :amount, ...])
    end

目前,我尝试使用发票表单的内部,例如:form_for

<%= form.fields_for @invoice.invoice_items.build do |lorem| %>

这让我在控制台中出现以下错误(但按预期保存发票:

Unpermitted parameter: :invoice_item. Context: { controller: InvoicesController, action: create, request: #<ActionDispatch::Request:0x000000010a0c8d88>, params: {"authenticity_token"=>"[FILTERED]", "invoice"=>{..., "invoice_item"=>{"invoice_id"=>"", "amount"=>"3"}}, "button"=>"", "controller"=>"invoices", "action"=>"create", "user_id"=>"1", "client_id"=>"1", "project_id"=>"1"} }

请注意,invoice_id不会传递给invoice_item。

通过控制台,类似

@invoice = Invoice.new
@invoice.invoice_items.new(amount: "3", ...)
@invoice.save!

确实工作得很奇怪,但它不能转化为我的代码。 我在这里做错了什么?

Ruby-on-Rails 红宝石 嵌套 嵌套形式 Ruby-on-Rails-7

评论


答:

0赞 Ben Garcia 9/7/2022 #1
# invoice_item_attributes is wrong
def invoice_params
  params.require(:invoice).permit(... :invoice_item, invoice_item_attributes: [:id, :invoice_id, :amount, ...])
end

应该是

# invoice_items_attributes is right
def invoice_params
  params.require(:invoice).permit(... :invoice_item, invoice_items_attributes: [:id, :invoice_id, :amount, ...])
end

注意缺少的“s”。https://www.ombulabs.com/blog/learning/rails/nested-forms.html

评论

0赞 GabrielTheCoder 9/7/2022
谢谢你的回答。不幸的是,这没有效果。
0赞 GabrielTheCoder 9/7/2022 #2

在遵循了 GoRails 关于如何在 rails 中正确设置嵌套表单属性的截屏视频后,我仍然遇到了错误。我最终可以追踪他们,并找到了这个简洁的帖子,哪个游戏提示使用和 .我不是 100% 确定这些是做什么的,即使我现在会阅读以找出答案,但我的东西现在工作正常:)inverse_ofautosave: true

修改后的模型

class Invoice < ApplicationRecord
  belongs_to :project
  
  has_many :invoice_items, inverse_of: :invoice, autosave: true
  accepts_nested_attributes_for :invoice_items
...