Rails5 Active Record 记录无效错误
Rails 5 Active Record Record Invalid Error
我有两个 Rails 模型,即 Invoice 和 Invoice_details。
一张Invoice_details属于到发票,一张发票有很多Invoice_details.
我无法在 Invoice[=] 中使用 accepts_nested_attributes_for 通过 Invoice 模型保存 Invoice_details 47=].
我收到以下错误:
(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
的代码片段:
class Invoice < ApplicationRecord
has_many :invoice_details
accepts_nested_attributes_for :invoice_details
end
invoice_details.rb
的代码片段:
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|
ActiveRecord::RecordInvalid (Validation failed: Invoice details
invoice must exist):
错误是由于您 不允许 invoice_id
在为 invoice
保存 invoice_detail
时
在Rails 5中,关联对象的存在将被默认验证。您可以通过设置 optional :true
绕过此验证
来自Guides
If you set the :optional option to true, then the presence of the
associated object won't be validated. By default, this option is set
to false.
解法:
允许 invoice_id
在 invoice_details_attributes
中 invoice_params
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
我仍然不知道上述事情不起作用的原因,但是当我明确声明两个 模型之间的 双向 关系时 通过使用 inverse_of
.
class Invoice < ApplicationRecord
has_many :invoiceDetails, inverse_of: :invoice
accepts_nested_attributes_for :invoiceDetails
end
似乎 Rails 没有在 invoice_details 上设置 invoice 属性 在尝试保存之前,触发了 validation 错误。这有点令人惊讶,因为其他 has_many 关系应该具有相同的保存机制并且工作得很好。
经过一些谷歌搜索后,我发现很少有关于此行为发生在旧版本 Rails 中的帖子,我不知道新版本中是否仍然存在。
可以在这些链接中进一步查看:
我有两个 Rails 模型,即 Invoice 和 Invoice_details。 一张Invoice_details属于到发票,一张发票有很多Invoice_details. 我无法在 Invoice[=] 中使用 accepts_nested_attributes_for 通过 Invoice 模型保存 Invoice_details 47=].
我收到以下错误:
(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
的代码片段:
class Invoice < ApplicationRecord
has_many :invoice_details
accepts_nested_attributes_for :invoice_details
end
invoice_details.rb
的代码片段:
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|
ActiveRecord::RecordInvalid (Validation failed: Invoice details invoice must exist):
错误是由于您 不允许 invoice_id
在为 invoice
invoice_detail
时
在Rails 5中,关联对象的存在将被默认验证。您可以通过设置 optional :true
来自Guides
If you set the :optional option to true, then the presence of the associated object won't be validated. By default, this option is set to false.
解法:
允许 invoice_id
在 invoice_details_attributes
中 invoice_params
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
我仍然不知道上述事情不起作用的原因,但是当我明确声明两个 模型之间的 双向 关系时 通过使用 inverse_of
.
class Invoice < ApplicationRecord
has_many :invoiceDetails, inverse_of: :invoice
accepts_nested_attributes_for :invoiceDetails
end
似乎 Rails 没有在 invoice_details 上设置 invoice 属性 在尝试保存之前,触发了 validation 错误。这有点令人惊讶,因为其他 has_many 关系应该具有相同的保存机制并且工作得很好。
经过一些谷歌搜索后,我发现很少有关于此行为发生在旧版本 Rails 中的帖子,我不知道新版本中是否仍然存在。 可以在这些链接中进一步查看: