Rails 5 Record Active Record Invalid Error

I have two Rails models, Invoice and Invoice_details . Element Invoice_details refers to to the invoice , and the counter has a lot Invoice_details. I cannot save Invoice_details via Invoice using accepts_nested_attributes_for in Invoice .

I am getting the following error:

(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'

      

Below is the code snippet for invoice.rb

:

class Invoice < ApplicationRecord
  has_many :invoice_details
  accepts_nested_attributes_for :invoice_details
end

      

Snippet of code for invoice_details.rb

:

class InvoiceDetail < ApplicationRecord
  belongs_to :invoice
end

      

Code 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

      

Raw JSON data is passed to the controller:

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

      

invoice_details schema

|id | invoice_id | product_id | created_at | updated_at|

      

invoice scheme

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

      

+3


source to share


2 answers


I still don't know the reason why the above thing didn't work, however, when I was explicitly declaring a bidirectional relationship between two models using inverse_of

.

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

      

It seemed like Rails didn't set the invoice attribute on invoice_details before trying to save it by calling validationstrong> errors. This is a bit surprising, since the other has_many relationships must have the same persistence mechanics and worked just fine.



After a bit of searching I found several posts about this behavior in the old version of Rails, I don't know if this exists in the newer version. Further you can see in these links:

0


source


ActiveRecord :: RecordInvalid (validation failed: invoice information must exist):

The error is due to the fact that you do not allow invoice_id

when saving invoice_detail

forinvoice

In Rails 5, the existence of a linked object will be checked by default. You can bypass this check by settingoptional :true

From Guides

If you set the option: optional to true, then the existence of the associated object will not be checked. By default, this option is set to false.

Decision:



Allow invoice_id

ininvoice_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

      

OR

If you don't want this, install optional :true

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

      

+5


source







All Articles