Rails неявная ошибка проверки на существование ассоциации - PullRequest
0 голосов
/ 11 февраля 2020

Я использую Rails 6.0.2.1.

У меня довольно простая модель между клиентами, счетами и предложениями. Счет-фактура относится к предложению (но это не обязательно - счет-фактура не обязательно должен основываться на предложении). Кроме того, счет-фактура принадлежит клиенту.

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
  ...

Эти модели не проверяются между собой. То есть у меня нет подтверждения, указывающего, что в счете-фактуре должно быть предложение или даже клиент. Однако Rails выдает мне ошибки проверки их существования, если я проверяю достоверность любого поля в счете:

> 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}]}>

Почему он отмечает отсутствующий клиент и отсутствующее предложение как ошибки существования?

1 Ответ

1 голос
/ 11 февраля 2020

Вы получаете сообщение об ошибке, потому что в Rails 5 и выше всякий раз, когда мы определяем ассоциацию own_to, требуется, чтобы соответствующая запись присутствовала по умолчанию.

Так что вам нужно связать клиента и предложение чтобы выставить счет, только тогда вы сможете создать объект счета. Это означает, что вам нужно это сделать -

client = Client.create
proposal = Proposal.create
inv = Invoice.new(client: client, proposal: proposal)

Вы также можете упомянуть отношение belongs_to как optional, тогда наличие связанного объекта не будет проверено

class Invoice < ActiveRecord::Base
  belongs_to :client, optional: true
  belongs_to :proposal, foreign_key: "prop_id", optional: true
  ...

С optional: true

inv = Invoice.new

не выдаст никаких ошибок

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...