【问题标题】:Rails 5 Active Record Record Invalid ErrorRails 5 Active Record 记录无效错误
【发布时间】:2017-06-17 13:11:11
【问题描述】:

我有两个 Rails 模型,即 InvoiceInvoice_details。 一个Invoice_details属于属于Invoice,一个Invoice有很多Invoice_details。 我无法使用 accepts_nested_attributes_for in Invoice 通过 Invoice 模型保存 Invoice_details

我收到以下错误:

(0.2ms)  BEGIN
(0.2ms)  ROLLBACK
Completed 422 Unprocessable Entity in 25ms (ActiveRecord: 4.0ms)         
ActiveRecord::RecordInvalid (Validation failed: Invoice details invoice must exist):
app/controllers/api/v1/invoices_controller.rb:17:in `create'

下面是invoice.rb 的代码 sn-p :

class Invoice < ApplicationRecord
  has_many :invoice_details
  accepts_nested_attributes_for :invoice_details
end

invoice_details.rb 的代码 sn-p:

class InvoiceDetail < ApplicationRecord
  belongs_to :invoice
end

Controller 代码:

class Api::V1::InvoicesController < ApplicationController
  respond_to :json

  def index
    comp_id = params[:comp_id]
    if comp_id
      invoices = Invoice.where(:company_id => comp_id)
      render json: invoices, status: 201
    else
      render json: { errors: "Company ID is NULL" }, status: 422
    end
  end

  def create
    Rails.logger.debug invoice_params.inspect
    invoice = Invoice.new(invoice_params)
    if invoice.save!
      render json: invoice, status: 201
    else
      render json: { errors: invoice.errors }, status: 422
    end
  end

  def invoice_params
    params.require(:invoice).permit(:total_amount,:balance_amount, :customer_id, invoice_details_attributes:[:product_id])
  end
end

传递给控制器​​的原始 JSON 数据:

{
    "invoice":{
        "total_amount":"100",
        "balance_amount":"0",
        "customer_id":"1",
        "invoice_details_attributes":[{
            "product_id":"4"
        }]
    }
}

invoice_details 架构

|id | invoice_id | product_id | created_at | updated_at|

发票架构

|id| total_amount |balance_amount | generation_date | created_at | updated_at | customers_id|

【问题讨论】:

  • 尝试在invoice_details_attributes of invoice_params 中添加invoice_id
  • 您可以发布发票详细信息的架构吗?那里的自动保存似乎出了点问题。
  • @Pavan 很好,我忘了 rails 5 现在验证 belongs_to,除非另有指示。
  • 有效果吗?

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-5


【解决方案1】:

ActiveRecord::RecordInvalid(验证失败:发票详情 发票必须存在):

错误是由于您不允许 invoice_id 同时将invoice_detail 保存为invoice

Rails 5 中,默认情况下会验证关联对象的存在。你可以通过设置optional :true来绕过这个验证

来自Guides

如果您将 :optional 选项设置为 true,则存在 关联对象不会被验证。默认情况下,此选项已设置 为假。

解决方案:

invoice_details_attributesinvoice_params 中允许invoice_id

def invoice_params
  params.require(:invoice).permit(:total_amount,:balance_amount, :customer_id, invoice_details_attributes: [:product_id, :invoice_id])
end

如果您不想这样做,请设置optional :true

class InvoiceDetail < ApplicationRecord
  belongs_to :invoice, optional :true
end

【讨论】:

  • 我确实将 invoice_id 添加到 permit 子句,但没有奏效,出现同样的错误。此外,我不希望发票详细信息是可选的,因为发票应至少提供一个详细信息。
  • 'def invoice_params params.require(:invoice).permit(:total_amount,:balance_amount, :customer_id, invoice_details_attributes:[:invoice_id,:product_id]) end'
【解决方案2】:

我仍然不知道上述事情不起作用的原因,但是当我使用 @987654324 明确声明两个 模型 之间的 双向 关系时@。

class Invoice < ApplicationRecord
  has_many :invoiceDetails, inverse_of: :invoice
  accepts_nested_attributes_for :invoiceDetails
end

在尝试保存 invoice_details 之前,似乎 Rails 没有设置 invoice 属性,触发了验证强>错误。这有点令人惊讶,因为其他 has_many 关系应该具有相同的保存机制并且工作正常。

经过一番谷歌搜索后,我发现很少有关于旧版本 Rails 中出现这种行为的帖子,我不知道新版本中是否仍然存在。 进一步可以在这些链接中查看:

  1. https://github.com/rails/rails/issues/6161#issuecomment-8615049
  2. https://github.com/rails/rails/pull/7661#issuecomment-8614206
  3. https://github.com/rails/rails/issues/6161#issuecomment-6330795

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多