Reputation: 58244
I'm running Rails 6.0.2.1.
I have a fairly simple model between clients, invoices, and proposals. An invoice belongs to a proposal (but this is optional - an invoice doesn't have to be based upon a proposal). Also, an invoice belongs to a client.
class Invoice < ActiveRecord::Base
belongs_to :client
belongs_to :proposal, foreign_key: "prop_id"
...
class Proposal < ActiveRecord::Base
belongs_to :client
has_one :invoice, foreign_key: "prop_id", dependent: :destroy
...
class Client < ActiveRecord::Base
has_many :proposals, dependent: :destroy
has_many :invoices, dependent: :destroy
...
These models have no validations between one another. That is, I do not have a validation indicating that an invoice must have a proposal or even a client. However, Rails is giving me validation errors on their existence if I check the validity of any field in the invoice:
> inv = Invoice.new
=> #<Invoice id: nil, client_id: nil, prop_id: nil, tocb_id: nil, fromcb_id: nil,
date_invoice: "2020-02-10", written_by: nil, terms: nil, date_due: nil,
status: "Pending", shipping: nil, amount: 0.0, amt_due: 0.0, deposit: nil,
tax_rate: nil, comments: nil>
> inv.errors.count
=> 0
> inv.valid? :amount
=> false
> inv.errors.count
=> 2
> inv.errors
=> #<ActiveModel::Errors:0x000056466dac7a38 @base=#<Invoice id: nil, client_id: nil,
prop_id: nil, ... , @messages={:client=>["must exist"], :proposal=>["must exist"]},
@details={:client=>[{:error=>:blank}], :proposal=>[{:error=>:blank}]}>
Why is it flagging missing client and missing proposal as existence errors?
Upvotes: 1
Views: 577
Reputation: 1812
You are getting the error because in Rails 5 and above, whenever we define a belongs_to association, it is required to have the associated record present by default.
So you need to link a client and a proposal to invoice, only then would you be able to create an invoice object. Which means you need to do this -
client = Client.create
proposal = Proposal.create
inv = Invoice.new(client: client, proposal: proposal)
You can also mention the belongs_to
relationship as optional
, then the presence of the associated object won't be validated
class Invoice < ActiveRecord::Base
belongs_to :client, optional: true
belongs_to :proposal, foreign_key: "prop_id", optional: true
...
With optional: true
inv = Invoice.new
will not give any errors
Upvotes: 3