I have a model Entity
that can have offers
and invoices
. The user can create custom mumber formats to display the invoice number. For example the internal invoice number 23
could become 2025INV00000023
or something like that. Now, for offers
, we need to be able to use a different number format. 23
there could become 2025OFF00000023
.
I have done this by creating a NumberFormat
class where the user can configure number formats in several ways. Number formats are attached to entities because all invoices from an entity need to have uniform/consistent numbering for tax/accounting purposes.
My Entity
model starts like this:
class Entity < ApplicationRecord
has_many :invoices, dependent: :restrict_with_error
has_many :offers, dependent: :restrict_with_error
some more unrelated has_many
belongs_to :invoice_number_format, class_name: 'NumberFormat'
belongs_to :offer_number_format, class_name: 'NumberFormat'
Now my NumberFormat
class needs to have the other end of the belongs_to
relationship. But I'm not sure if the doubling there is the correct approach in order to have a dependent: :restrict_with_error
preventing the user from deleting number formats that are still in use. VSCode's autoformatter just deletes the second one on save. I can of course save without formatting (and take great care to not forget whenever editing this file) and after preliminary testing it seems like it works but I'm wondering if my approach is maybe not ideal?
has_many :entities, inverse_of: :invoice_number_format,
dependent: :restrict_with_error
# This line gets deleted on save
has_many :entities, inverse_of: :offer_number_format,
dependent: :restrict_with_error
You can have any number of associations pointing to the same model but each association needs to have a unique name or you will just overwrite the previous definition and it's methods.
class Entity < ApplicationRecord
belongs_to :invoice_number_format,
class_name: 'NumberFormat'
inverse_of: :entities_as_invoice_number_format
belongs_to :offer_number_format,
class_name: 'NumberFormat
inverse_of: :entities_as_offer_number_format
end
class NumberFormat < ApplicationRecord
has_many :entities_as_invoice_number_format,
inverse_of: :invoice_number_format,
dependent: :restrict_with_error,
foreign_key: :invoice_number_format_id,
class_name: 'Entity'
has_many :entities_as_offer_number_format,
inverse_of: :offer_number_format,
dependent: :restrict_with_error,
foreign_key: :offer_number_format_id,
class_name: 'Entity'
end
The foreign_key
and class_name
options are required here as they are derived from the name of the assocation.